OmniAICreator/Qiita-1.07M huggingface dataset:
【FileMaker】タイマーを仕掛ける　その１


FileMaker Advent Calendar 2015 10日目の記事です。
10日続いてよかったです。。。

今回は、「タイマー」です。
「その１」なので、「その２」あります^^

あまり使ったことなかったのですが、最近使う機会がありまして。

**スクリプト一時停止/続行**

というコマンドです。
こんなことできます。

system3に注目です。
![スクリーンショット 2015-12-06 14.53.41.png](https://qiita-image-store.s3.amazonaws.com/0/60538/7ad9d58e-fcaa-f9f0-5a29-7668cc1d998e.png)
この状態で、「処理実行」ボタンを押してみましょう。

処理中になりました。
![スクリーンショット 2015-12-06 14.53.50.png](https://qiita-image-store.s3.amazonaws.com/0/60538/6724734a-2863-92e9-6773-a4dc889e24fa.png)

10秒後、処理終了となります。
![スクリーンショット 2015-12-06 14.54.00.png](https://qiita-image-store.s3.amazonaws.com/0/60538/abd49f2d-3566-cb14-6309-486b31679cdc.png)

ここで何を処理させるかは、なんでもいいんですが、例えば作業画面は出したくないからダミーの画面を表示させておくとか制限時間付きの入力テストをするとか、考えられますね。

スクリプトとしては、こんな感じになります。
![スクリーンショット 2015-12-06 14.53.10.png](https://qiita-image-store.s3.amazonaws.com/0/60538/05d98818-5d44-63c3-d1c3-174cb7fd0d19.png)

system3は、グローバル変数にしてありますが、サンプルなので適当です。
「ウィンドウ内容の再表示」は、諸々処理をした時に結果（集計とかODBC接続でのデータ再表示など）を再表示するので、今回のような単純な処理ではあってもなくても大丈夫です。

この仕掛けを使って、次回はサンプルを作ってみます。
OpenCVの線形システム・最小二乗問題ソルバcv::solve

#連立一次方程式

```math 
AX=B
```

を満たすｘを求める問題は非常に良く使う数値計算です．解法アルゴリズムとしては，様々なものがあります．

* シンプルに逆行列A<sup>-1</sup>を求める（数値計算に詳しい研究室だとまずはじめに教えられること．「**逆行列の計算はやってはいけない．遅すぎる．**」O(n<sup>3</sup>)．）
* ガウスの消去法　（O(n<sup>3</sup>)．逆行列を求めるのと同じ．遅すぎる．講義で習った方法．）
* LU分解（O(n<sup>3</sup>)）
* コレスキー分解(Cholesky)
* 固有値分解

最小二乗問題を解く場合．Aが正則な行列ではない場合
* 特異値分解
* QR分解

#OpenCVの実装
OpenCVでは，これを`cv::solve`で提供しています．下記関数は，線形システム（入力行列Aが正則，非特異である場合）か，最小二乗問題を解く関数．

`bool cv::solve(InputArray A, InputArray B, OutputArray X int flags=DECOMP_LU)`

flags:
* *DECOMP_LU*: LU分解
* *DECOMP_CHOLESKY*: コレスキー分解． 行列Aは正定値対称行列であること．LU分解より高速．
* *DECOMP_EIG*: 固有値分解．行列Aは対称行列であること．
* *DECOMP_SVD*: 特異値分解（singular value decomposition: SVD）
* *DECOMP_QR*: QR分解（現在，SVDをかわりに呼び出す実装になっているためSVDと答えが同じです．いいのか！？）．
* *DECOMP_NORMAL*: 上記以外だった場合，下記システムをかわりに解く．

```math 
A^TAX=A^TB
```

実装では，LU分解やコレスキー分解は，halモジュールを読んでいます．固有値分解ではヤコビ法を自前で実装して解いています．
特異値分解では，JacobiSVD法を自前で実装して解いています．QR分解はSVDと同じとして，SVDで解いてます．条件が揃えば，SVDは固有値分解と同じになるため演算が速い固有値分解をコールするように作られています．
詳細はopencv/core/lanpack.cppのコードを参照してください．

しかしながら，精度や速度を考えるとより適切なアルゴリズムが多く提案されています．Eigenは以下の演算がモジュールとして用意されるほど数値計算方法が充実しています．もし，大きな行列の線形解法が必要なときは，速度・精度の面からOpenCVのソルバを使うのが適切か一度検討してみましょう．

* LU
* Cholesky
* Householder
* SVD
* QR
* Eigenvalues

#まとめ
OpenCVの線形ソルバについてまとめました．
線形ソルバとしてはOpenCVは小回りを利かせるためには，必要最低限のものはそろえていますが，充実しているとはいえません．
より深く勉強するためには，[Eigenのチュートリアル](http://eigen.tuxfamily.org/dox/group__TutorialLinearAlgebra.html)などが参考になります．
また，この[スライド](http://yebisu.cc.kyushu-u.ac.jp/~watanabe/LECTURE/INA/05.pdf)やこの[資料](http://yebisu.cc.kyushu-u.ac.jp/~watanabe/RESERCH/MANUSCRIPT/TUTORIAL/leq.pdf)も良くまとまっています．
solveするにもいろいろあるということが分かると思います．
Herokuを使おう

Herokuって言葉だけは良く出て来ますが、一体何ぞやということで、
オレオレ評価です。
正統な評価は、他のQiitaやブログを参照してください。
あくまで主観です。

[Heroku](https://www.heroku.com/) : https://www.heroku.com/

# 何が出来るのか？

Node, Ruby, Java, PHP, Python, Go, Scala, Clojure の各種言語のプラットフォームが
あらかじめ用意されているクラウドサービス

言語のプラットフォーム部分はすでに用意されているので、コードをGitから持ってくれば
すぐに動作が出来る。 

# どういう利点があるの？

開発環境用途やベータリリース環境、リリース開始時の小規模環境のクラウドリソースとして
無料で使える。（ただし、ある程度のリソース占有をしてしまうと有料になる）

# Herokuのいけていないところ

・Gitが基本なのでソースのやり取りとかは、全てGitが基本。
・デザイン素材もGit経由でデプロイしないといけない。
・DBがPostgreSQLだけなところ。
・ほとんどがGitのコマンドプロンプトで操作するところ。
・時々、無料で使えるプランが変更になることろ。

# まあ、そうは言っても

・ベータリリースでちょっと公開したい時
・期間限定の短時間だけ公開したい時
・お試しサービスとしてちょっとだけ公開したい時

には、無料で使える範囲で公開させて貰えるのは良いのではないかな？

# Herokuの不安なところ

昔からお金にうるさい世界的企業のＳ社に買収されてしまったので、
マネタイズしたくてウズウズしてそうなのがちょっと見え見えで気になる。

あのＳ社がフリーでオープンソースに貢献するだけだとは思えないんですよねぇｗ


しかし、作成したサービスが将来大規模にスケールすることを考えたら、
Heroku単体ではすぐに限界が来たり、プラットフォーム部分をカスタマイズ出来る範囲が限られるので、
AWSやAzureなんかの他のクラウドサービスを使った方が良いかもしれない。
ActiveTypeで機能別モデルを実現


Ruby on Railsでは、ビジネスロジックはモデルに載せるということになっていますが、どうしてもモデルが肥大化しがちです。そんな時に使える切り分け手法として、`ActiveType`があります。

# Fat Controller→Fat Model→クラスごと分ける
何も考えずにRailsでコードを書いていくと、ついついControllerにビジネスロジックを寄せてしまうことになります。これは、「Fat Controller」と呼ばれて、あまり良くないパターンとされています。

それでは、これらをモデルに移していくとどうなるでしょうか。同じようなパターンの処理をモデルとしてくくり出せるうちはいいのですが、すべての場合の処理をモデルに出していっても、それはそれで今度はモデルが肥大化してきてしまいます。これもこれで、コードの動作がわかりづらくなってしまいます。

ということで、いちばんの理想形は、「実現すべきビジネスロジックに対応して、細かくモデルを切り出す」ということになります。[ActiveType](https://github.com/makandra/active_type)は、それを支援するための強力なツールとなります。

# テーブルに対応しないモデル…`ActiveType::Object`
テーブルに対応しないモデルを作るときに、別に基底クラスはなくても構わないのですが、そうするとフォームヘルパーやバリデーションといった、`ActiveRecord::Base`で用意されている機能が全く使えないモデルとなってしまいます。情報取得だけの場合など、それでも全く支障がないこともあるのですが、とりわけ入力を受け付けるような場合には不便極まりありません。いちおう、`ActiveModel`の各種モジュールを`include`すればそれらの機能にも対応はしますが、正しく書くだけでひと仕事になってしまいます。

そこで、基底クラスとして`ActiveType::Object`を使えます。これは、実際に`ActiveRecord::Base`を継承した上で、DBアクセスだけを殺したものとなっています。ということで、バリデーション、コールバック、リレーションといった、DB書き込み以外のすべての機能を通常のActiveRecordと同様に使えます。DBがないので、属性は`attribute`を使って宣言する必要があります。

なお、`accepts_nested_attributes_for`については、ActiveType特有の記法に直す必要がある、とのことです。

```rb:models/no_db_model.rb
class NoDbModel < ActiveType::Object
  attribute :name, :string
  attribute :price, :integer
  attribute :parent_id

  validates :price, numericality: {greater_than: 0}
  belongs_to :parent
end
```

# テーブルに対応したモデルを継承する…`ActiveType::Record[BaseClass]`
Railsで作るような業務システムの根幹は、データの変換にあります。入力フォームへ行った人間の入力からモデルのデータへ、そしてDBのレコードにしたり、逆に表示の時はDBからモデルへ変換し、そしてモデルからHTMLやJSONとしてデータを取り出す、そういうのがメインの流れです。

ときには、イレギュラーな変換が入ることがあります。たとえば、CSVや他サービスからのデータ取り込みなどです。もちろんこれらもモデルが担うべき部分ではあるのですが、全部1本のモデルに書いていては冗長になってしまうだけなので、「特殊化」として、クラスを継承してそちらに実装できればすっきりします。

ただ、ふつうにActiveRecordのクラスを継承すると、シングルテーブル継承として働いてしまうため、「同じモデルに特殊な機能を加える」という、意図した効果は得られません。

ここでもActiveTypeの出番です。クラスを`ActiveType::Record[BaseClass]`から継承させると、データベースの読み書きは`BaseClass`として行われるのですが、継承した先のクラスとして、特殊な機能が使えるようになります。正しい継承関係なのかどうかは確認していませんが、ここで継承したクラスのインスタンスについて、`.is_a?(BaseClass)`もtrueを返すので、ビューで表示させるときなどにそのまま通常のモデルがわりに使っても問題ありません（`ActiveType.cast`を使うと1オブジェクト、あるいはリレーション単位でキャストもできます）。

```rb:継承の例
# user.rb
class User < ActiveRecord::Base
end

# csv_user_importer.rb
class CsvUserImporter < ActiveType::Record[User]
  def self.import
    # 略
  end
end

```
Windows標準でDvorak

## Windows標準でDvorak

Dvorak Advent Calendar 10日目．


レジストリエディタ(regedit.exe)で

`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00000411`

のLayout Fileを「KBDJPN.DLL」から「KBDDV.DLL」に変更すれば、Dvorak配列になります．

-----

（現場によっては勝手にツール等が使えない上にキーボード持ち込みもできないようなケースがあると思います．そんな時の最後の手段として）
PHP7でCakePHP3を動かしてみる

PHP7上でCakePHP3動かしてみる

つい先日公開されたPHP7を使ってCakePHP3を動かしてみます。
ついでに簡単なベンチマークでも取ってみようと思います。

### 基本環境

- CentOS 7.1(VM)
- Apache 2.4

## CakePHP3+PHP7インストール

PHP7のインストールにはおなじみのRemiを使わせてもらいました。

```
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum --enablerepo=remi-php70,epel install php php-cli php-common php-mbstring php-fpm php-gd php-gmp php-mbstring php-mcrypt php-opcache php-pdo php-xml php-mysql php-intl
```

php確認
```
php -v
PHP 7.0.0 (cli) (built: Dec  1 2015 17:53:27) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
```

Composer&CakePHP3インストール
``` 
curl -sS https://getcomposer.org/installer | php
php composer.phar create-project --prefer-dist cakephp/app cake3
```

## ベンチマーク

~~今回比較用にPHP7+CakePHP2、PHP5.6+CakePHP3、PHP5.6+CakePHP2を用意しました。~~
一通りやったけどトップページじゃさすがに速度変わりませんでしたorz

対象ページはトップページにしておきます。

``` 
ab -n 10 -c 10 http://localhost/cake3/
```

|　|CakePHP3|CakePHP2|
|:-:|:-:|:-:|
|PHP7|505ms|508ms|
|PHP5.6|507ms|512ms|

今度何かシステム作った時に改めて測り直します。

## 結論

**触りだけですけどCakePHP3,CakePHP2系ともに問題なく動きました！！**
knockoutのsubscribe

    この記事は、knockout.js Advent Calendar 2015の１０日目の記事です。 先に９日目に目を通すことを推奨しています。
    knockout , knockout-es5 , knockout.punches環境を想定しています。

subscribeはライトユーザは、ほとんど利用することがないかもしれません。　（解説：　[公式](http://knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables)、[日本語](http://kojs.sukobuto.com/docs/observables#explicitly_subscribing_to_observables)）

subscribeを用いると、値が変化した際のイベントハンドラを設定できます。
subscribeは、observableに対して設定をしてあげる必要があるため、knockout-es5を利用している際にはひと手間かかります。
knockout-es5においてobservableを取得するには、``ko.getObservable({someObject},'property-name')``を行います。
これで、observableが取得できるので、このobserveableに対してsubscribe(変更通知）を設定します。

今回は、例として　ユーザ名の変更を検知してみました。[これがその**サンプル**](http://jsfiddle.net/MKGaru/1dm9zvob/)です。

```js:javascript
ko.getObservable(this,'myName').subscribe(function(myName){
	alert('名前が、'+myName+'に変わりました');
});
```

------------------------------------------------------------------------------

`変更後の値`および`変更前の値`を同時に取得したい場合は、

```js:javascript
ko.subscribable.fn.subscribeChanged = function (callback) {
    var savedValue = this.peek();
    return this.subscribe(function (latestValue) {
        var oldValue = savedValue;
        savedValue = latestValue;
        callback(latestValue, oldValue);
    });
};
```
というものを定義してあげるといいでしょう。　([参考](https://github.com/knockout/knockout/issues/914#issuecomment-66697321))

[このように](http://jsfiddle.net/MKGaru/ya3yxe38/)利用できます。

```js:javascript
function VM(){
    this.myName= "山田";
    ko.track(this);
    ko.getObservable(this,'myName').subscribeChanged(function(myName,old){
        alert('名前が、'+old+'から、'+myName+'に変わりました');
    });
};
```
DlangUI de Dlang-man

#D言語くんかわいい
![dman_optimized.gif](https://qiita-image-store.s3.amazonaws.com/0/77773/868f85a0-0325-f2a1-c90b-cccdd21b8b60.gif)

ボタンを押すと「D言語くんかわいい」と表示されます。D言語くんかわいい。

##ソースコードの説明

```d:app.d
import std.stdio;
import std.random;
//サンプルコードにはdlangui.allと書いてるけどこう
import dlangui;

//サンプルコードにはDLANGUI_ENTRY_POINTと書いてるけど変わってる
mixin APP_ENTRY_POINT;

extern(C) int UIAppMain(string[] args)
{
	Platform.instance.uiLanguage = "ja";
	//UIのテーマを設定
	Platform.instance.uiTheme = "theme_default";

	//Windowを生成
	auto window = Platform.instance.createWindow("Hello World!",null);
	//日本語フォントの読み込み。デフォルトでは豆腐になった
	auto jaFont = FontManager.instance.getFont(20,FontWeight.Normal,false,FontFamily.MonoSpace,"JKゴシックM");
    //HorizontalLayoutを継承した「D言語くん可愛い」の文字が表示されるウィジェット
	auto layout = new DmanLayout(jaFont);
	//D言語くんクラス。画像表示するだけ
    auto dman = new Dman;
    //ボタン。Buttonを継承してフォントを変更出来るようにした
	auto btn = (new JaButton(jaFont)).text("D言語くん可愛い!!!");
	//ボタンが押された時に実行されるデリゲートを代入。引数で渡されるsrcはイベントの起こったWidget
        btn.onClickListener = delegate(Widget src)
		{
			layout.kawaii(); //「D言語くん可愛い」を表示
			return true;
		};
	layout.addChild(dman);
	layout.addChild(btn);
        //Windowにlayoutを追加
	window.mainWidget = layout;
	//表示
        window.show();
     //メッセージループ突入
	return Platform.instance.enterMessageLoop();
}

class DmanLayout : HorizontalLayout
{
private:
    //「D言語くん可愛い」を描画する位置の集合
	Point[] textPositions;
	FontRef jaFont;
	this(FontRef jaFont)
	{
		this.jaFont = jaFont
		backgroundColor = 0xFFFFC0;
	}
    //JavaのSwingで言うところのpaint。
	override void onDraw(DrawBuf buf)
	{
        //親メソッドのonDrawを呼び出す。これをしないと背景が描画されなかったり
		super.onDraw(buf);
        //すべての「D言語くん可愛い」を再描画
		foreach(str;textPositions)
			jaFont.drawText(buf,str.x,str.y,"D言語くん可愛い",0xFF0000);
	}
	void kawaii()
	{
		auto rndX = uniform(0,width);
		auto rndY = uniform(0,height);
		textPositions ~= Point(rndX,rndY);
		//onDrawの呼び出しを要求する
        invalidate();
	}
}

class Dman:Widget
{
private:
        DrawBuf image;
	this()
	{
                //画像をロード。DrawBufを継承したColorDrawBufというものが返ってくる
		image = loadImage("compiler-dmd.png");
                //ピクセル数も簡単に取得
		layoutHeight = image.height;
		layoutWidth = image.width;
	}
	override void onDraw(DrawBuf buf)
	{
		super.onDraw(buf);
        //渡されたDrawBufに描画
		buf.drawImage(0,0,image);
	}
}

class JaButton:Button
{
private:
        FontRef jaFont;
	this(FontRef jaFont)
	{
		this.jaFont = jaFont;
        //最大の高さを設定
        maxHeight = 100;
	    //余白の設定
        margins = Rect(50,50,50,50);
    }
    //fontメソッドをオーバーライドして使用されるフォントを変更
	override FontRef font() @property const
	{
		return cast(FontRef)jaFont;
	}
}

struct Point
{
	int x,y;
}               
```

DlangUIなかなか楽で楽しいです。デリゲートを使ったりとD言語の機能を使えるのがなかなかいいです。D言語くんかわいい
AWS SESの通知（バウンス、苦情、配信）を自動で取得し、保存

## SESの通知管理の重要性

AWS SESの通知には、バウンス、苦情、配信がありますが、
これらの中でも、一番重要なのは、バウンスではないかと思われます。
AWS SESのハードバウンスに対する対応は、なかなか辛辣です。

一度ハードバウンスが返却されれば、
Suppression Listにメールアドレスが登録されます。
AWSのコンソールでSuppression Listからメールアドレスを削除しなければ、
その宛先に対し、最大2週間メール送信することができなくなります。

また、送信メールのバウンス率が高くなると、
SESのサービスそのものを止められてしまいます。

こういったリスクを最小限に止めるためにも、
バウンスの管理は非常に重要と言えます。
また、本来、バウンスと苦情を管理できなければ、
サンドボックス制限を解除してはいけません。


## 通知の受け取り方
管理については、以下のドキュメントに記載されています。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/notifications-via-email.html

ドキュメントにある通り、バウンスの通知を受け取る方法には、
大きく分けて2通りあります。
SESから直接Eメールで通知を受け取る方法と、
AWS SNS経由で、他のサービスと連携する方法です。

Eメールでの通知のみであれば、SESのコンソール画面だけで設定を完了できます。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/notifications-via-email.html
しかし、自社のDBにバウンスを保存するといった場合には、SNSを利用する方が容易です。

##利用サービス
ここでは、定期処理でバウンスを取得する場合でのAWSの設定を解説します。

SESの他に、下記のサービスを利用します。
### SNS
SESから通知を受け取り、SQSにバウンスの通知内容を送信
### SQS
SNSから通知を受け取り、外部から通知内容を取り出し可能に


# 手順
SNSに、SESからのバウンスを受け取るためのトピックを作成します。

###SNSトピック作成

SNS Homeから、Create Topicを選択します。
name, Display nameは分かりやすい名前をつけます。

###SES通知設定 
受け取りたい通知の対象に応じ、
DomainsかEmail Addressを選択します。
遷移後、通知対象のURLをクリックします。
Notificationを選択し、続いて、Edit Configurationを選択します。
ダイアログ中の、SNS Topic ConfigurationのBouncesで、
先ほど作成したSNSトピックを選択します。

###残りの手順（SNSから、SQSにメッセージを送信する設定）
ここまでの手順で、SESからSNSに対して通知が送信されるはずです。
SNSからSQSにメッセージを送信する方法は、
下記のドキュメントを参照してください。
http://docs.aws.amazon.com/ja_jp/sns/latest/dg/SendMessageToSQS.html

以上の作業で、SQSにメッセージが蓄積されるはずです。
あとは、定期処理でSQSからメッセージを取得し、
DBで保存すれば、自前の環境でバウンスの一覧を参照できるようになります。



今回はバウンスで解説しましたが、
他の通知に関しても同様の方法で通知を取得可能です。

##注意
バウンスのテストをする時には、
テスト用のメールアドレスを利用するようにしてください。
そうしなければ、バウンス率が上がってしまいまい、
最悪、SESサービスが利用できなくなります。
テスト用のメールアドレスは、下記のドキュメントに記載されています。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html
幸せを追求しているといつのまにか不幸のスパイラルに入ることがある話

エンジニアはものづくりで貢献することが好き。
程度の違いはあれど、誰もが自分のテクで、チームに、プロジェクトに、ユーザーに貢献したいという想いはあると思います。そんな想いで活動していて、「あれ？なんか思っていたのと違うな？」という状況に陥ったことはありませんか？

## バッドストーリー

### フェーズ1：ネタを見つけて対応する

ある日あなたは、それほど関わりのないチームでの困りごとを発見します。それは Excel マクロなのか bookmarklet なのか Shell なのか分かりませんが、何かしらの手段を講じれば自動化できそう。

![qiita1.png](https://qiita-image-store.s3.amazonaws.com/0/15769/d6fa5f03-e8ff-7ba5-99c1-d58a554c92bc.png)

そんなわけで空き時間を見つけて対応。共有して使ってもらい、「おお、これは便利」という声をもらいます。「もうちょっとこんな風にしてほしいんだけど…」という声にもタイムリーに対応。

![qiita2.png](https://qiita-image-store.s3.amazonaws.com/0/15769/e688b39d-4f56-3a47-e431-54c99ddb9e90.png)

チームの作業は効率化され、あなたは承認欲求が満たされ、なかなか良い感じです。これは幸せになれるかもしれない。



### フェーズ2：色々なことに首を突っ込み出す

自分が貢献できるネタは色々なところに転がっているのではないか？そんなあなたは嗅覚するどくネタを発掘し、次々に技術面からの対策を打っていきます。

![qiita3.png](https://qiita-image-store.s3.amazonaws.com/0/15769/8093f8c5-4a25-ac56-f9e0-809147cdf528.png)


顔も広がり、あなたは求められる存在に。

### フェーズ3：手を広げすぎて対応しきれなくなってくる

そうはいっても半分ボランティアの活動。あなたは主たる業務があります。便利マンだけになっているわけにはいきません。色々なチームから、提供したツールの改修・改善依頼が飛んできますが、複数ネタを一気にさばくのは難しい。

![qiita4.png](https://qiita-image-store.s3.amazonaws.com/0/15769/0d262d16-c4ac-39f0-c7e1-f720204dc53a.png)


必死に時間外にも対応しますが、後手後手の対応にならざるを得ません。これはまずい。

### フェーズ4：各所からのヘイトが溜まってソウルジェムが濁る

便利機能を提供していたはずが、「それがあって当たり前」のモノになってくると、動かないことに対しての鬱憤が溜まります。その鬱憤はあなたにむけて発せられ、人づてに悪い評判も耳に入ってくるようになります。

![qiita5.png](https://qiita-image-store.s3.amazonaws.com/0/15769/9e2dc41e-acb4-3405-3aa0-2f13a147f4e7.png)


おかしい、皆の幸せを追求したはずなのに、なんでこんなことになっているんだ。

魔女（あるいは魔王）の誕生です。

## 落とし穴

エンジニアはものづくりで貢献することが好き。
ときにこれが落とし穴になることがあります。
あなたには自己顕示欲は無いかもしれません。けれど「自分が作ったもの」で貢献したい、という想いはあるかもしれない。これが罠です。

こんなバッドエンドにならないために、意識しておくと良いことを紹介します。

## 対策

### 対策1：相手に「仕組み」を共有する

あなたが提供するものが何なのか、どう動くのか、修正したい場合はどこをどう直すのかも共有してしまいましょう。メールやチャットで共有するのではなく、時間を取って対面で、目の前で実際に修正する様子を見せてあげると効果的です。いきなり全ては引き取ってくれることは期待できないかもしれませんが、そのうち、自分たちでメンテナンスできるよう期待して、オープンに共有していきましょう。

### 対策2：仲間を増やす

自分ひとりがヒーローになる必要はありません。同じ問題意識を抱えた仲間を作りましょう。相互に貢献できる組織が作れるように、仲間を増やしていきましょう。自分１人しかメンテナンスできないものを作らないことが理想ですね。


## まとめ

あいつら本当に好き勝手いいやがって！

そんな一言が口をついて出たら、もしかしたら視野が狭くなってしまっているかもしれません。
もともと、皆の幸せを追求していたはず。
原点に立ち返って、その実現のためには何をすべきか？を考えられると良いですね。

年の瀬に、チームのあるある話を書いてみました。


※この話はフィクションです
VimでGitのブランチ毎にセッションを簡単に保持できるようにする

この記事はクラウドワークス Advent Calendar 2015 10日目の記事になります。
趣味のdotfilesいじりの中で、最近使い始めた`Vim`の設定の紹介です。

## 背景
`Git`で管理されているディレクトリ下で作業している時、あるブランチの変更はレビュー待ちだから新しいブランチを切って別の作業を進めよう、なんて事を繰り返していたら、あれよあれよと言う間にブランチが増えて、いつの間にか複数のブランチを股にかけて作業をしているという事がありますが、そうなった時に一度でも`Vim`を閉じようものなら、作業しやすいように積んでいたバッファとかタブの順番とかウィンドウの状態が全てまっさらになってしまうので、再度作業しやすい状態にするという作業が繰り返されて結構なストレスになっていました。こういう繰り返しの作業は撲滅したいです。

## `vim-session`を使用して快適にする
`Vim`の`mksession`というコマンドを使って`Vim`の状態(`session`)を保存することはできますが、その`session`を扱いやすくしてくれるプラグインもあるので、今回は`vim-session`を使って改善する事にしました。

#### インストール
```vim
NeoBundle 'xolox/vim-session', {
  \ 'depends': 'xolox/vim-misc'
\ }
```
#### 設定
```vim
" session保存ファイル名
let g:session_default_name = '.session'
" session保持ファイルの拡張子
let g:session_extension = '.vim'
" session保存ディレクトリを現在のディレクトリにする
let g:session_directory = getcwd()
" vim終了時に自動保存しない
let g:session_autosave = 'no'
" 引数なしでvimを起動した時にセッションを復元しない
let g:session_autoload = 'no'
" 1分間に1回自動保存をしない
let g:session_autosave_periodic = 0
```
上記のような設定を行ってから`Vim`のコマンドラインモードで`SaveSession`コマンドを実行すると、カレントディレクトリに`.session.vim`というファイルが作成されて`Vim`の状態が保存されるようになります。復元したい場合は`OpenSession .session`です。

## `fugitive.vim`を使用して更に快適にする
ここまでの設定でひとまず状態の保存と復元がやりやすくなったのですが、まだいまいち使い勝手が良くありません。やりたいのは複数のブランチを股にかけて作業するような時に、簡単に状態を保存・復元できるようにする事なので`Vim`用の`git`ラッパープラグインである`fugitive.vim`を使って更に改善してみます。

#### インストール
```vim
NeoBundle 'tpope/vim-fugitive'
```

#### 設定
```vim
" session保存ファイル名
let g:session_default_name = '.default.session'
" session保持ファイルの拡張子
let g:session_extension = '.vim'
" session保存ディレクトリを現在のディレクトリにする
let g:session_directory = getcwd()
" vim終了時に自動保存しない
let g:session_autosave = 'no'
" 引数なしでvimを起動した時にセッションを復元しない
let g:session_autoload = 'no'
" 1分間に1回自動保存をしない(する場合は1)
let g:session_autosave_periodic = 0

function! s:save_session(...)
  if a:0
    let session_name = a:1
  else
    " fugitive.vimの機能を使っているのはブランチ名を取得する部分のみ
    " substitute(system('git rev-parse --abbrev-ref HEAD'), '\n', '', 'g')などで代替可能
    let session_name = fugitive#head()
  end

  if strlen(session_name)
    execute 'SaveSession .'.session_name.'.session'
  else
    SaveSession
  endif
endfunction

function! s:load_session(...)
  if a:0
    let session_name = a:1
  else
    let session_name = fugitive#head()
  end
  
  if strlen(session_name)
    execute 'OpenSession .'.session_name.'.session'
  else
    execute 'OpenSession '.g:session_default_name
  endif
endfunction

command! -nargs=? SaveS call s:save_session(<f-args>)
command! -nargs=? LoadS call s:load_session(<f-args>)
```
この設定で新しく`SaveS`と`LoadS`というコマンドが定義されます。`SaveS`と`LoadS`は引数なしで実行すると`.#{現在のブランチ名}.session.vim`というファイル名で状態の保存と復元を行うので、ブランチ毎の状態を簡単に扱う事ができるようになります。これでやっと使いやすくなりました。

## まとめ
`Vim`を使っている時間は長いので、小さな改善でもすぐに効果が実感できるのがいい所です。

## 参考URL
- [vimでウィンドウやタブの状態を自動保存/復元する方法](http://qiita.com/take/items/3be8908bbf4ad5b49e46)
- [xolox/vim-session](https://github.com/xolox/vim-session)
- [tpope/vim-fugitive](https://github.com/tpope/vim-fugitive)
[Android]多言語化対応したときにアプリ名の対応を忘れていた話

qnote Advent Calendar 2015 の 10日目を担当する横田です。

3日目に引き続き、Androidの多言語化についての備忘録です。

ソースコード内に埋め込まれた日本語の表記をすべてstrings.xmlに移行して、複製して各言語用のフォルダを作り、そこにstrings.xmlを複製して、翻訳結果を反映して、対応完了！

と、思っていたら、アプリ名の対応を忘れていました…。

##対応方法

1. strings.xmlを開く
2. `<string name="app_name">Sample</string>`といった感じでアプリ名を追加
3. AndroidManifest.xmlの`android:label`を`android:label="@string/app_name"`にする

上記の手順をstrings.xmlの数分だけ繰り返せば、アプリ名の多言語化の対応ができるかと思います。
【vte.cx入門】9.画像をアップロードし参照する：jQuery実践編

ここでは画像の登録と参照の方法について説明します。

FormDataオブジェクトをajax通信でPOSTすることで画像データを登録することができます。

# 1.ajaxでFormData（画像データ）を登録する（POSTリクエスト）
jQueryのajax通信を使用し、POSTリクエストを実行します。

```lang:HTML
<form id="form">
<input type="file" id="file" name="picture">
<input type="submit" id="submitBtn" value="登録する">
</form>
```

```lang:javascript
$('#submitBtn').on('click', function(evt) {

    var form = $('#form').get()[0];
    var formData = new FormData( form );

    $.ajax({
        url: '/d/hoge',
        method: 'post',
        dataType: 'json',
        data: formData,
        processData: false,
        contentType: false
    }).done(function( res ) {
        alert('画像登録成功');
    }).fail(function( jqXHR, textStatus, errorThrown ) {
        alert('画像登録失敗');
    });
    return false;
});
```
## ■リクエスト
| param | 値 | 例 |
|:-----------|:------------|:------------|
|url|登録先URL|/d/hoge|
|method|POST||
|dataType|json||
|data|formデータ||
|processData|false||
|contentType|false||

### ファイル名の禁止文字
ファイル名はキーになるため、キーで使用できない文字は指定できません。
キーに含まれる名前には英数字と$、_(アンダースコア)が使えます。

## ■レスポンス
### 成功ステータス

| ステータス | メッセージ | レスポンス |
|:-----------|:------------|:------------|
|200|OK|{"feed" : {"title" : "参照先URL"}}|

成功したら、レスポンスに画像の参照先URLが格納されています。
そこにアクセスすることで画像に参照できます。

/d/hogeを登録先としたら、/d/hoge/{画像ファイル名}が参照先になります。

### 失敗ステータス
その他のエラーの場合、以下の仕様書の下部に細かく記載されています。
[HTTPステータス一覧](http://reflexworks.jp/documentation.html#taggingservice.html#H)

#### 「URI must not contain any prohibited characters」エラー（ステータスコード400）
このエラーが発生した場合は、ファイル名に禁止文字が含まれています。
ファイル名を修正し、もう一度試してみてください。

# 2.画像データ参照する
画像登録時にレスポンスで返却されたURLにそのままアクセス(GET)するとバイナリデータが返却されます。

```
http://{自分のサービス}/d/参照先URL
```

画像が表示できたら成功です。

# 終わりに
画像アップロードの詳しい仕様は[こちら](http://reflexworks.jp/documentation.html#taggingservice.html#P4)をご参照ください。
サーバーサイドJavascriptを使用し、複数の画像を一度に登録する方法などが記載されています。

次回は共有フォルダの作成方法を説明します。
Swiftのブロックの省略形

Swiftの長所として私は配列等のメソッドチェーンやりやすさがあると感じます。
Objective-cと比べるとSwiftはメソッドが短いしブロックをシンプルに書けるのでメソッドチェーンが気持よく書けます。

```swift
["1", "2", "3", ""].flatMap { Int($0) }.filter { $0 < 2 }.map { $0 * 2 } // [2]
```

今回はブロックの省略方法をsortメソッドを例に書いていこうと思います。

## 通常の書き方
sortメソッドは省略せずに書くと以下のようになります。

```swift
let arr = [1, 2, 3]
arr.sort({ (value1: Int, value2: Int) -> Bool in
   return value1 < value2
})
```

## 型の省略
型推論によって型を省略できます。

```swift
let arr = [1, 2, 3]
arr.sort({ (value1, value2) in
   return value1 < value2
})
// sortメソッドの方に型情報が書いてあるので省略できる
// public func sort(@noescape isOrderedBefore: (Self.Generator.Element, Self.Generator.Element) -> Bool) -> [Self.Generator.Element]
```

()も省略できます。

```swift
let arr = [1, 2, 3]
arr.sort({ value1, value2 in
   return value1 < value2
})
```

## 引数の省略
第一引数、第二引数は$0、$1に置き換える事ができます。
ブロック内が短い時はこの書き方をする事が多いです。

```swift
let arr = [1, 2, 3]
arr.sort({
   return $0 < $1
})
```

## returnの省略
ブロックの中身が1行の時はreturnも省略できます。
1行で処理を書く時に便利です。

```swift
let arr = [1, 2, 3]
arr.sort({ $0 < $1 })
```

最後の引数がブロックの時は{}を外に出すことができます。

```swift
let arr = [1, 2, 3]
arr.sort() { $0 < $1 }
```

ブロック以外の引数がない場合、()も省略できます。

```swift
let arr = [1, 2, 3]
arr.sort { $0 < $1 }
```

最初と比べるとすごいシンプルになりました。

```swift
let arr = [1, 2, 3]
arr.sort({ (value1: Int, value2: Int) -> Bool in
   return value1 < value2
})
// ↓
arr.sort { $0 < $1 }
```

## おまけ
sortは下の書き方もできます。

```swift
let arr = [1, 2, 3]
arr.sort(<)
```

< の実態は下のような関数なので、sortの引数として渡すことができます。

```swift
public func <(lhs: Int, rhs: Int) -> Bool
```
正規表現で取りうる値をすべて取得する方法

# やりたいこと
* **その正規表現が表している文字列**をすべて取得したい
* 具体的には、クローラを作る時にクローリング対象URLを正規表現で指定したい
* ↓こんなかんじ

### インプット
```
http://xxx/abc[x-z]/image(9|10|11).png
```

###　取得したい値
```
http://xxx/abcx/image9.png
http://xxx/abcy/image9.png
http://xxx/abcz/image9.png
http://xxx/abcx/image10.png
http://xxx/abcy/image10.png
http://xxx/abcz/image10.png
http://xxx/abcx/image11.png
http://xxx/abcy/image11.png
http://xxx/abcz/image11.png
```

# やり方
* [google/sre_yield](https://github.com/google/sre_yield/)を使う

```sample.py
import sre_yield

if __name__ == '__main__':
    regex = r'http://xxx/abc[x-z]/image(9|10|11)\.png'
    urllist = list(sre_yield.AllStrings(regex))
    print(urllist)
```

```console:実行結果
['http://xxx/abcx/image9.png', 'http://xxx/abcy/image9.png', 'http://xxx/abcz/image9.png', 'http://xxx/abcx/image10.png', 'http://xxx/abcy/image10.png', 'http://xxx/abcz/image10.png', 'http://xxx/abcx/image11.png', 'http://xxx/abcy/image11.png', 'http://xxx/abcz/image11.png']
```

* [sre_yield](https://github.com/google/sre_yield/) は [最近StackOverFlowで教えてもらった](http://stackoverflow.com/questions/33827603/can-i-create-list-from-regular-expressions)ライブラリです。
* 正規表現を展開する方法、あまり需要がないのかネットで探してもなかなか辿りつけなかったのでまとめました。
* それにしても、**StackOverFlowに足を向けて寝れません**。
Ctrl+qで終了したら困るアプリケーションを終了しないようにする

1分で実現できる有用な技術 Advent Calendar 2015 10日目担当のしょっさんです！

今回は簡単に出来て、かつ汎用的に有用性がある「Ctrl+qでアプリケーションを終了しないようにする」方法の紹介です。

## 前置き

Mac上でアプリケーションを終了する際のコマンドとして「Ctrl+q」がありますが、GoogleChromeやターミナルなど普段終了しないアプリケーションにとっては誤爆の種になる困った存在になります。

そこで、「Ctrl+q」で終了したくないアプリケーションには「終了する」アクションのショートカットに別のキーコンフィグを設定しましょう。

## やり方

今回は例として、GoogleChromeへの対応を行います。

まず、Macの「システム環境設定」→「キーボード」→「ショートカット」を開きます。

---

![スクリーンショット_2015-12-06_17_18_48.png](https://qiita-image-store.s3.amazonaws.com/0/39382/84a0b26b-c634-a7c6-d26d-8044fdc9ea24.png)

![スクリーンショット_2015-12-06_17_23_25.png](https://qiita-image-store.s3.amazonaws.com/0/39382/be96c23d-8bfd-e374-9f42-6bea2fad94eb.png)

![スクリーンショット_2015-12-06_17_23_35.png](https://qiita-image-store.s3.amazonaws.com/0/39382/ab290623-fb69-923e-f477-fd672f5a84e3.png)

---

次に、左メニューの「アプリケーション」を選択し、+ボタンをクリックします。
すると「アプリケーション」と「メニュータイトル」、「キーボードショートカット」の入力画面が表示されます。
「アプリケーション」には「Google Chrome.app」を、「メニュータイトル」にはGoogleChromeでのメニュー上で表示されている終了アクションの名称を、「キーボードショートカット」には割り当てたいキーコンフィグを入力します。

---

![スクリーンショット_2015-12-06_17_23_35.png](https://qiita-image-store.s3.amazonaws.com/0/39382/4f24b29f-a0be-c2c1-41c5-4f1c0a1a7195.png)

![スクリーンショット 2015-12-06 17.27.00.png](https://qiita-image-store.s3.amazonaws.com/0/39382/88e1a38a-4176-08c8-bdd7-b091398c417a.png)

![スクリーンショット_2015-12-06_17_28_09.png](https://qiita-image-store.s3.amazonaws.com/0/39382/a4d62ceb-22a9-179e-4a5e-29cd7840d30e.png)

---

そうすることで、終了する際のキーボードショートカットが変更されます！
GoogleChromeのみだけでなく、他のアプリケーションにも対応出来ますので他にも終了させたくないアプリケーションがありましたら対応してみてください。
WindowsでNASMを使ってアセンブラを動かしてみる


Windows環境下でアセンブラを動かしてみたくて，NASMを使ってみたのでメモ

# 結論
`$ nasm -fwin32 hello_world.asm`
`$ link hello_world.obj /ENTRY:main /SUBSYSTEM:CONSOLE /defaultlib:kernel32.lib`

で行けました．

# 環境
* OS
	* Windows7 32bit
* アセンブラ
	* NASM
* リンカ
	* VisualStudio 付属のlink.exe

を使います．

## NASM
こちらからダウンロード
http://www.nasm.us/

（本記事作成時の最新安定版のリンクはこちら
http://www.nasm.us/pub/nasm/releasebuilds/2.11.08/win32/nasm-2.11.08-win32.zip )

zipアーカイブ内の`nasm.exe`がnasm本体ですので，コンパイル等は必要なくそのまま使えます．

## リンカ
Visual Studio2015付属の`link.exe`を用いました．

スタートメニュー内の`Visual Studio 2015 > Visual Studio Tools > 開発者用コマンドプロンプト for VS2015`を用いると，元々PATHが追加されているので楽ちんです．`link`と打つだけで実行出来ます．

自分でPATHを追加しても構いません．その場合は，開発者用コマンドプロンプトで`where link`を実行すると，`link.exe`の置いてある場所が表示されるのでそれを参考にしてください．

# 動かすアセンブラ
`Hello, World` を表示するだけの簡単なアセンブラです.
アセンブラの説明は本記事から外れるので省きます．

今回，`printf`等のライブラリ関数を使いたくない理由があったので，`WriteFile`を用いて標準出力へ出力しています．

```hello_world.asm
  global _main

  extern  _GetStdHandle@4
  extern  _WriteFile@20
  extern  _ExitProcess@4


  section .text

_main:
  ; DWORD bytes;
  ;  <- prepare local variable
  mov     ebp,  esp
  sub     esp,  4

  ; hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
  ;       (STD_OUTPUT_HANDLE = -11)
  push    -11
  call    _GetStdHandle@4
  mov     ebx, eax

  ; WriteFile( hStdOut, msg, length(msg), &size, 0)
  push    0
  lea     eax, [ebp - 4]
  push    eax
  push    (message_end - message)
  push    message
  push    ebx
  call    _WriteFile@20

  ; ExitProcess(0)
  push    0
  call    _ExitProcess@4

  ; never here
  hlt

message:
  db      'Hello, World', 10
message_end:

```

(本アセンブラの参考元 : http://stackoverflow.com/questions/1023593/how-to-write-hello-world-in-assembler-under-windows/1029093#1029093 )

# 実行形式を作成する
2つのステップを踏みます．

1. アセンブラをCOFF形式のオブジェクトファイルに変換
2. オブジェクトファイルをリンカで実行形式に


## アセンブラをCOFF形式のオブジェクトファイルに変換
今回はWindows 32bit版のものを作りますので，`-f`オプションで`win32`を指定します．

`$ nasm -fwin32 hello_world.asm`

上記コマンドでCOFF型式のオブジェクトファイルである`hello_world.obj`が生成されます．

## オブジェクトファイルをリンカで実行形式に
`$ link hello_world.obj /ENTRY:main /SUBSYSTEM:CONSOLE /defaultlib:kernel32.lib`


* `/ENTRY`でエントリポイントの指定します(今回は`main`
* `/SUBSYSTEM`で「Win32 文字モード アプリケーション」であることをリンカに伝えます．
* `/defaultlib`で`GetStdHandle`等を呼び出すためのライブラリを指定します．

これで`hello_world.exe`が生成されたはずです．
あとは実行しましょう．

Hello, World!!!
Office UI Fabricでちょっとだけ実用的なアプリを作ってみる

今日は手前味噌的なネタになってしまいすが、Office UI Fabric(以下"OfficeUI")ちょっとだけ実用的なアプリを作成してみました。これまでOfficeUIの基本的なUI部品やレイアウト方法の紹介をしてきましたが、実際にどんな感じのアプリが作成できるの？という点をフォローできればと思います。

## 一行メモ保存・検索ツール

(スクリーンショットのタイトルが違うけど)OfficeUIで一行メモを入力し、Local Storageに保存するというツールです。Local StorageのデータはJSONでエクスポート・インポートが可能です。

 * 一行メモ保存・検索ツール
   * [http://furandon_pig.bitbucket.org/sample/officeui/json_export/](http://furandon_pig.bitbucket.org/sample/officeui/json_export/)

スクリーンショットは以下のようになります。実は元々JavaScriptでデータをLocal Storageに保存して、データはJSONでエクスポート・インポートを行えるようにすればサーバがなくても(ある程度のアプリは)実現できるかも！という安易な思いつきで作成したアプリに「ついでだからOfficeUIも使ってみよう」というノリで作成したものです。

OfficeUIを使用してアプリを作成するとこんな感じになるのか〜、という感じで試してみてもらえればと思います。

![img400.png](https://qiita-image-store.s3.amazonaws.com/0/61137/9c7e2b27-df5e-2d0c-6959-6da37a67df3d.png)

## まとめ

今日はOfficeUIで作成したアプリを紹介してみました(今日はバタバタしてあまりAdvent Calendarに時間がかけられなかったというのが正直なところです……)。明日はOfficeUIのダイアログボックスについて解説したいと思います。
underscoreコードリーディング（findWhere）



underscoreに詳しくないので、勉強半分でソースコードを読む。



##利用するバージョン
[underscore.js(v1.8.3)](https://github.com/jashkenas/underscore/tree/1.8.3)


##findWhereとは


###[underscorejs.orgのfindWhere](http://underscorejs.org/#findWhere)

こんな説明。
>####_.findWhere(list, properties) 
>Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
>If no match is found, or if list is empty, undefined will be returned.

```javascript
_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
=> {year: 1918, newsroom: "The New York Times",
  reason: "For its public service in publishing in full so many official reports,
  documents and speeches by European statesmen relating to the progress and
  conduct of the war."}
```

------------- 
エイリアスは特になし。

listのなかで最初に、propertiesの中のすべてのkey-valueペアにマッチするものを返してくれる。
もし、マッチするものが見つからなかった、もしくはリストが空だった場合にはundefinedを返却する。



###[underscore.findWhere](https://github.com/jashkenas/underscore/blob/1.8.3/underscore.js#L294)

コード的にはこのあたり。

```javascript
  // Convenience version of a common use case of `find`: getting the first object
  // containing specific `key:value` pairs.
  _.findWhere = function(obj, attrs) {
    return _.find(obj, _.matcher(attrs));
  };
```

_.findと_.matcherを用いて、マッチしたもののうち先頭のものを返却する。


。
_.matcherはObjectに対して利用できるattrsで定義されているkey-valueと同じものが存在するかを判定できる関数を返す。

[underscore.matcher](http://underscorejs.org/#matcher)

```javascript
matcher_.matcher(attrs) Alias: matches 
Returns a predicate function that will tell you if a passed in object contains all of the key/value properties present in attrs.

var ready = _.matcher({selected: true, visible: true});
var readyToGoList = _.filter(list, ready);
```

[_.matcher](https://github.com/jashkenas/underscore/blob/1.8.3/underscore.js#L1306)

```javascript
_.matcher = _.matches = function(attrs) {
  attrs = _.extendOwn({}, attrs);
  return function(obj) {
    return _.isMatch(obj, attrs);
  };
};
```

_.matcherの中身は_.isMatch関数を返すものなので

[_.isMatch](https://github.com/jashkenas/underscore/blob/1.8.3/underscore.js#L1082)

```javascript
_.isMatch = function(object, attrs) {
    var keys = _.keys(attrs), length = keys.length;
    if (object == null) return !length;
    var obj = Object(object);
    for (var i = 0; i < length; i++) {
      var key = keys[i];
      if (attrs[key] !== obj[key] || !(key in obj)) return false;
    }
    return true;
  };
```


つまり

```javascript
  _.findWhere = function(obj, attrs) {
    return _.find(obj, function(obj, attrs){
    
      var keys = _.keys(attrs), length = keys.length;
      if (object == null) return !length;
      var obj = Object(object);
      for (var i = 0; i < length; i++) {
        var key = keys[i];
        if (attrs[key] !== obj[key] || !(key in obj)) return false;
      }
      return true; 
    });
  };
```

となっている。
Tweak on Tweak

この記事は [iOS Jailbreaking Advent Calendar 2015](http://qiita.com/advent-calendar/2015/ios-jailbreaking) の9日目の記事です。

# はじめに
[@r-plus](https://twitter.com/r_plus?lang=ja) の記事面白いですね。私は、最近CydiaSubStarteアドオンを作って遊んでいませんので、以前遊んでいたことを思い出しながら書いてみようと思います。

# TweakのTweakについて考える
[CCNowPlaying](https://github.com/wakinchan/CCNowPlaying)でAuxo 3に対してのTweakを実現して、Auxo 3のViewの上に対してボタンを配置していました。

![alt](https://raw.githubusercontent.com/wakinchan/CCNowPlaying/master/Screenshot/Screenshot_iOS8_auxo3.png)

CydiaSubstrateはプロセスが読み込まれる際に、アルファベット順で `/Library/MobileSubstrate/DynamicLibraris` のdylibをロードするようです。もし自分のdylibが引っ掛けたいdylibより名前が若ければ引っ掛けれませんよね。
そういった場合、SpringBoardのロード後に `%init` を実行し、擬似的に遅延ロードを起こしています。
また、対象とするdylibのロードのタイミングが違う場合は、それによって適宜ロードするタイミングを変えてやります。

```objc++
%hook SpringBoard
- (void)applicationDidFinishLaunching:(id)application
{
    %orig;
    if (IS_IOS8()) {
        %init(Auxo3);
    }
}
%end
```

`%init(hoge)`の`hoge`に関しては、[@r-plus](https://twitter.com/r_plus?lang=ja) の7日目の記事に書かれている[Meta class hooking.](http://qiita.com/r_plus/items/1fed1bfa386a4fd37f1d)と同じですね。
その結果、このような感じでAuxo 3に対してExtension出来ます。

```objc++
%group Auxo3
%hook UminoControlCenterBottomView
- (void)scrollViewWillBeginDragging:(UminoControlCenterBottomScrollView *)scrollView
{
    [self alphaButtonWithScrollView:scrollView];
    %orig;
...
```
stl2povを使ってSTLファイルのD言語くんをPOV-Rayに降臨させる

# はじめに

こんにちは。123D Designマスター（D言語くん部門）の @simd_nyan です。
今日はstl2povでSTLファイルを変換し、POV-Rayでレンダリングする方法についてまとめます。

![cornell.png](https://qiita-image-store.s3.amazonaws.com/0/98084/573ff828-80a1-99e4-0037-a24cc1839400.png)

## [POV-Ray](http://www.povray.org/)とは

OSSの3Dレンダリングエンジンです。3DCGをスクリプトで書くという特徴があります。
古くからあるソフトウェアですが、今でも高校や大学の授業で使われているそうです。

## [py-stl / stl2pov](http://rsmith.home.xs4all.nl/software/py-stl-stl2pov.html)

その名の通り、STLファイルをPOV-Rayで使えるファイルに変換するPythonのスクリプトです。
C言語で実装されたものもダウンロードできます。環境に応じて使い分けて下さい。

# 使い方

## 変換

```bash
stl2pov d-man.stl
```

`-2`オプションで`mesh2`オブジェクトに変換できます。

```bash
stl2pov -2 d-man.stl
```

123D Designが出力するSTLファイルはオブジェクト名が`ascii`なので、出力される`mesh`オブジェクト名が`m_ascii`になります。また、`cornell.pov`に降臨させるとオブジェクトが反転します。
不便なのでスクリプトを書き換えます。

```diff
--- stl2pov.py.org
+++ stl2pov.py
@@ -38,29 +38,29 @@
     print ver
     print "Usage: stl2pov infile [outfile]"

-def mesh1(s):
+def mesh1(s, name):
     '''Returns a string containing the Surface s as a POV-ray mesh object.'''
-    ms = "# declare m_{} = mesh {{\n".format(s.name)
+    ms = "# declare {} = mesh {{\n".format(name)
     sot = "  triangle {{ // #{}\n"
     fc = "    <{1}, {0}, {2}>,\n"
     fct = "    <{1}, {0}, {2}>\n"
     for n, f in enumerate(s.facets):
         ms += sot.format(n+1)
-        ms += fc.format(f.v[0].x, f.v[0].y, f.v[0].z)
-        ms += fc.format(f.v[1].x, f.v[1].y, f.v[1].z)
-        ms += fct.format(f.v[2].x, f.v[2].y, f.v[2].z)
+        ms += fc.format(-f.v[0].x, f.v[0].y, f.v[0].z)
+        ms += fc.format(-f.v[1].x, f.v[1].y, f.v[1].z)
+        ms += fct.format(-f.v[2].x, f.v[2].y, f.v[2].z)
         ms += "  }\n"
     ms += "}\n"
     return ms

-def mesh2(s):
+def mesh2(s, name):
     '''Returns a string containing the Surface s as a POV-ray mesh2 object.'''
-    ms = "# declare m_{} = mesh2 {{\n".format(s.name)
+    ms = "# declare {} = mesh2 {{\n".format(name)
     numkeys = [(i, k) for (i, k) in enumerate(s.vertices.keys())]
     ms += '  vertex_vectors {\n'
     ms += '    {},\n'.format(len(numkeys))
     for (i, k) in numkeys:
-        ms += '    <{1}, {0}, {2}>,'.format(s.vertices[k].x, s.vertices[k].y,
+        ms += '    <{1}, {0}, {2}>,'.format(-s.vertices[k].x, s.vertices[k].y,
                                           s.vertices[k].z)
         ms += ' // vertex #{}\n'.format(i)
     i = ms.rindex(', //')
@@ -103,10 +103,11 @@
 outs += "// The abovementioned coordinates are in the STL file's right-handed\n"
 outs += "// coordinate system, while POV-ray uses a left-handed system.\n"
 outs += "// You should swap the x and y above to get POV-ray coordinates.\n"
+object_name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
 if oldmesh:
-    outs += mesh1(stlobj)
+    outs += mesh1(stlobj, object_name)
 else:
-    outs += mesh2(stlobj)
+    outs += mesh2(stlobj, object_name)
 # Write output to file.
 if len(sys.argv) < 3:
     # Derive output name
```

## レンダリング

シーンファイルの中でオブジェクトをインクルードし、任意の場所に配置してレンダリングします。

# おわりに

stl2povによるSTLファイルの変換方法と、POV-Rayでレンダリングする方法についてまとめました。
最新の3DCGソフトには敵わないものの、POV-Rayは様々な使い方ができるので、もう少し記事を書く予定です。
速習Perl6の日付型

こんばんは :whale2: 

[Perl 6 Advent Calendar 2015](http://qiita.com/advent-calendar/2015/perl6)の9日目です。

今回は`Date`と`DateTime`クラスをざっとながめてみたいと思います。

## Dateクラス

```pl
use v6;

# 今日
say my $today = Date.today; #=> 2015-12-09

# 翌日
say $today.succ;            #=> 2015-12-10

# 前日
say $today.pred;            #=> 2015-12-08

# 年/月/日
say $today.year;            #=> 2015
say $today.month;           #=> 12
say $today.day;             #=> 9

# うるう年？
say $today.is-leap-year;    #=> False

# 月の何日目？
say $today.day-of-month;    #=> 9

# 何曜日？
say $today.day-of-week;     #=> 3

# 年の何日目か
say $today.day-of-year;     #=> 343

# 年の何週目か
say $today.week.[1];        #=> 50

# この月何日まであるか
say $today.days-in-month;   #=> 31

# 2015年のクリスマス
say my $christmas = Date.new(2015, 12, 25); #=> 2015-12-25

# クリスマスまで何日
say $christmas - $today;    #=> 16

# 元旦(こういう指定もできます)
say my $newyear = Date.new(year => 2016, month => 1, day => 1); #=> 2016-01-01
```

## DateTimeクラス

以下、何故か`rb`(Ruby)を指定してソース貼り付けしてます[^ruby]

```rb
use v6;

# タイムゾーン '+09:00' 設定
my $*TZ = + 9 * 60 * 60;

# 元旦
put my $newyear = DateTime.new(
  year   => 2016,
  month  => 1,
  day    => 1,
  hour   => 21,
  minute => 15,
  second => 59,
  ).local; #=> 2016-01-02T06:15:59+09:00

# 2015年のクリスマス
put my $christmas = DateTime.new(
  :year(2015),
  :month(12),
  :day(25),
  ).local; #=> 2015-12-25T09:00:00+09:00


# 今日
put my $today = DateTime.new( time ).local; #=> 2015-12-09T22:35:24+09:00

# 今
put $today.now;      #=> 2015-12-09T22:35:24+09:00

# 時/分/秒
put $today.hour;     #=> 22
put $today.minute;   #=> 35
put $today.second;   #=> 24

# タイムゾーン確認 32400 ( = 9 * 60 * 60 )
put $today.timezone; #=> 32400

# 前日
say $today.earlier(days => 1);   #=> 2015-12-08T22:35:24+09:00

# 翌日
say $today.later(days => 1);     #=> 2015-12-10T22:35:24+09:00

# 翌月
say $today.later(months => 1);   #=> 2016-01-09T22:35:24+09:00

# タイムスタンプ
say $today.posix;                #=> 1449668124

# 標準時だと
say $today.utc;                  #=> 2015-12-09T13:35:24Z
```

## (おまけ)演算子オーバーロード

```pl
use v6;

# 2015年のクリスマス
say my $christmas = DateTime.new(
  :year(2015),
  :month(12),
  :day(25),
  ).local; #=> 2015-12-25T09:00:00+09:00

# 今日
say my $today = DateTime.new( time ).local; #=> 2015-12-09T22:35:24+09:00


## 演算子オーバーロード
# DateTime型同士で引き算して日付を返せるように
multi infix:«-»(DateTime $a, DateTime $b --> Int) {
  DateTime.new(($a.posix - $b.posix).Int, :timezone($a.timezone), :formatter($a.formatter)).day;
}

# クリスマスまで何日
say $christmas - $today; #=> 16
```

おわりです。

# 参考と注釈

* [Perl 6 Documentation - class Date](http://doc.perl6.org/type/Date)
* [Perl 6 Documentation - class DateTime](http://doc.perl6.org/type/DateTime)
* [Day 16: Time in Perl6 - Perl 6 Advent Calendar 2010](https://perl6advent.wordpress.com/2010/12/16/day-16-time-in-perl6/)
* [supernovus/perl6-datetime-math](https://github.com/supernovus/perl6-datetime-math/)
* [Perl の DateTime 利用上の注意点 - Perl 5 Advent Calendar 2015](http://shogo82148.github.io/blog/2015/12/09/perl-datetime/)

[^ruby]: [QiitaのシンタックスハイライトがまだPerl6に対応してないみたいどうしよう](http://qiita.com/B73W56H84/items/633b0c5fda663e313b59)
[phina.js]SpriteSheetを使ってみよう！

#はじめに
**phina.js**とはゲームが簡単に作れる*JavaScript*のライブラリです。
詳しくはこちらを参照してください。
[とりあえず試してみたいって方のための phina.js 入門 | phiary](http://phiary.me/phinajs-tutorial-try/)

#SpriteSheetってなに？
**SpriteSheet**の前に、スプライトアニメーションについて説明します。
スプライトアニメーションとは、アニメーションの各コマ画像を一枚画像の中にタイル状に配置し、画像内での表示位置を連続で切り替えることで、アニメーションを実現させる手法です

こんな感じの画像の１フレームづつ切り替えて
![ぴよぴよ](https://qiita-image-store.s3.amazonaws.com/0/31052/b53e5acc-ab49-fcaa-03b0-c6e5e815d3dc.png)　

この様な形で表示します（１～４フレーム目を繰り返してます）
![ぱたぱた](https://qiita-image-store.s3.amazonaws.com/0/31052/a644d67b-3cf4-5465-099f-2794c3093c7f.gif)

[frameIndexによるスプライトアニメーションサンプル
(runstant)](http://goo.gl/YUd1aQ)

上記サンプルでは**Sprite**の**frameIndex**を変化させて実現してますが、プログラム内で現在、フレームの何番目を表示するかを指定し、さらにプログラム内で任意の速度でフレームを進める様に制御しなくてはなりません。

これはいかにも面倒で、また、画像の変更にも弱い感じの方法です。
これを分かり易く、ｎ番のフレームからｎ番のフレームは○○のアニメーションと名前を付けて定義をしたものが**SpriteSheet**です。

#使い方
**SpriteSheet**として、下記の様に*JSON形式*で書いたファイルを用意します。
拡張子は何でもＯＫですが、この記事中では**SpriteSheet**という事で.ssを使用しております。
（注：JSONにはコメントが付けられませんが、説明の為に付加してます。コピペする場合はコメントを全て削除してください）

```json:hiyoko.ss
{
    //画像情報
    "frame": {
        "width": 32,    //１フレームの横幅
        "height": 32,   //１フレームの縦幅
        "cols": 6,      //横のフレーム数
        "rows": 3       //縦のフレーム数
    },

    //アニメーション情報
    "animations" : {
        "start": {              //アニメーション名
            "frames": [0,1,2,3],//表示するフレーム番号を配列として並べる(０始まり)
            "next": "start",    //アニメーション終了時、次のアニメーションを指定
                                //ループさせたい場合は自分を指定する
            "frequency": 5      //フレーム毎の間隔
        }
    }
}
```


このファイルを**SpriteSheet**のアセットとして読み込みます。

```js:sample.js
var ASSETS = {
  //ひよこの画像
  image: {
    'hiyoko': 'https://rawgit.com/minimo/phina.js_advent_20151212/master/hiyoco_nomal_full.png',
  },
  //SpriteSheet
  spritesheet: {
    'hiyoko_ss': 'https://rawgit.com/minimo/phina.js_advent_20151212/master/hiyoko_short.ss',
  }
};
```

**SpriteSheet**を**FrameAnimation**で読み込み、**Sprite**にアタッチします。

```
var piyo = Sprite('hiyoko', 32, 32);
var ss = FrameAnimation('hiyoko_ss')
ss.attachTo(piyo);

```

アタッチ後に**gotoAndPlay**で再生するアニメーションを指定します。

```
ss.gotoAndPlay('start');
```

これで**SpriteSheet**通りにアニメーションが再生されます。
詳しい手順はサンプルを参照してください。

[SpriteSheetとFrameAnimationによるスプライトアニメーションサンプル
(runstant)](http://goo.gl/Nt1A0R)

#まとめ
**frameIndex**を使用したスプライトアニメーションは手軽ですが、プログラム内である程度制御する必要があり、構造が複雑になりがちです。
そこで**SpriteSheet**を使用してアニメーション制御を任せてしまえば、プログラムも見通しがよくなるのでは無いでしょうか（主観）
便利な機能ですので使ってみてください！！

この記事で使用した画像とSpriteSheet置き場です[github](https://github.com/minimo/phina.js_advent_20151212)
ひよこの画像は[萬楽活戯大系](http://banraku-games.sakura.ne.jp/)（[@CarasOhmi](http://twitter.com/carasohmi)さん）よりお借り致しました。
ありがとうございます。
Laravel5.1 testingにin-memoryなsqliteを使う

一通りまとまった情報が見つからず、時間を食ったのでまとめ。
キャッシュのクリアを忘れてひどい目にあった。
やりたいことは表題の通り。

## 必要なパッケージの追加

composer.jsonに追加

```composer.json
{
    "require-dev": {
        // ...
        "doctrine/dbal": "^2.5"
    },
    //...
}
```

インストール

```
$ composer update
```

## database.phpに設定を追加

```config/database.php
    'connections' => [

        'sqlite' => [
            // ...
        ],

        // 以下を追加
        'sqlite_testing' => [
            'driver' => 'sqlite',
            'database' => ':memory:',
            'prefix' => '',
        ],
```

### phpunitで使用するDB設定を指定

testingの時、上記の設定を使うようにDB_CONNECTIONの行を追加
phpunit.xmlを環境ごとに変えたいこともあるかもしれないので
そういう時はphpunit.xml.defaultなどを作成したほうがいいかもしれない。

```phpunit.xml
    <php>
        ....
        <env name="DB_CONNECTION" value="sqlite_testing"/>
    </php>
```

注意!!!
ここで設定のキャッシュをクリア
気づかないと辛い目に遭う

```
$ php artisan config:clear
```

## DatabaseMigrations trait

テストごとにdbのmigrateとresetをする。
setUp()でArtisan::call('migrate')を呼ぶ方法もあるみたいだけど
DatabaseMigrationsトレイトを使う方が簡単と思われる。

```
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ExampleTest extends TestCase
{
    use DatabaseMigrations; // 追加

    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        // your test
    }
}
```

## テスト用データ投入

factoryが用意されてるので以下参照
Userクラスのfactoryが初めから書かれている。

```/database/factories/ModelFactory.php
$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->email,
        'password' => bcrypt(str_random(10)),
        'remember_token' => str_random(10),
    ];
});
```

### 使い方

```
public function testSeeUser()
{
    $user = factory(App\User::class)->make([
        'name' => 'marisa' //各fieldは自由に上書きできる
    ]);
    $user->save();
    $this->seeInDatabase('users', ['name' => 'marisa']);
}
```
NSUserDefaultsのちょっと賢いと思った使い方

すごい小ネタですが、いいなと思ったのでメモ。

以下のようなデータの形を持ちたいと考えていました。

```lang:swift
[
  ["ID": "1", "name": a],
  ["ID": "2", "name": b], 
  ["ID": "3", "name": c], 
]
```

辞書型のデータを配列で持つって感じですね。
ちょっとしたデータだったのでわざわざCoreData使うまでもないなと思ったので
UserDefaultsを使おうと途中まで書いていました。

がしかし、途中で実はこれちょっとまずったなと思いました。
基本的にIDからnameを引こうと思っていたので、毎回配列の中身を見てIDをみるのってあんまり賢くないなと。。
大したデータ量じゃないのでパフォーマンス的に問題なかったのですが、もっといい方法ないかなーと思い先輩に相談した所、以下のように保存すればいいんじゃない？とアドバイスもらいました

```lang:swift
let ud = NSUserDefaults.standardUserDefaults()
ud.setObject(name, forKey: "hogehoge_" + ID)
```

おお、確かにこれならいざ値を使う時にID渡すだけで検索になっていい！
データベース作るまでもないならこれぐらいで十分だし早く書けるしシンプルでいいなと思ったのでメモです。

あと、余談ですが毎回UserDefaultsを初期化してsynchronizeするのはちょっとしょっぱいので
ラッパークラスを作るともっとシンプルにかけてよさそうですね。

```lang:swift
class HogeUserDefaults {
    private class func userDefaults() -> NSUserDefaults {
         return NSUserDefaults.standardUserDefaults()
    }

    class func setObject(object:AnyObject, key:String) -> Void {
          self.userDefaults.setObject(name, forKey: "hogehoge_" + "ID")
          self.userDefaults.synchronize()
    }
}


class Hoge {
    func save() {
      HogeUserDefaults.setObject(object,key)  // 一行で簡単呼び出し！
    }
}
```

短いですが以上です！
Goで複数の画像を束ねてアニメーションSVGをつくるコマンドを書いた


[Github: high5/picsv](https://github.com/high5/picsv)



下記のコマンドは、
[ドロイドちゃん](http://droid-chan.net/) を歩かせて、途中で鳥を飛ばしたり、雪を降らせたりするサンプルです。

```
$ picsv -o output.svg \
-pics_1 background.gif \
-pics_2 front_1.gif,front_2.gif,front_3.gif,front_4.gif \
-pics_3 bird_1.gif,bird_2.gif,bird_3.gif,bird_4.gif \
-begin_3 3.5 \
-repeat_3 1 \
-pics_4 snow_1.gif,snow_2.gif,snow_3.gif,snow_4.gif \
-begin_4 6.5 \
-repeat_4 3 \
```

作成したSVGは下記のように動作します。

[output.svg](http://high5.science/sample_svg.html)

※ IEでは動作しないです。

内部的には、base64エンコードしたimageを SVGのanimate要素<animate>で制御して、＊.svgとしてアウトプットしています。
animate要素を使ったアニメーションSVGは単一のファイルで細かい制御ができて、gifオルタナティブな感じがして個人的にはいいなと思っていたのですが、作成したsvgを表示させてchromeのinspectを開くと、
SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.　と表示されるようになってました。
下記の記事にあるように、animateは将来的にはChromeではサポートされなくなる可能性があるみたいです。
[Chrome 45 BetaからSVGのSMILアニメーションが非推奨に](http://ssvvgg.net/post/127068682345/2015%E5%B9%B408%E6%9C%8819%E6%97%A5%E3%81%AEsvg)
[SVGアニメーションの現状](http://postd.cc/the-state-of-svg-animation/)
AddComponentを楽にする

ちょっとだけAddCompoentする作業が楽になるかも。
AddComponentMenu属性と引数にパスをいれる。パスは自由にいれてOK。

```csharp
using UnityEngine;
using System.Collections;

[AddComponentMenu("AAA/BBB/CCC")]
public class TestAddComponentMenu : MonoBehaviour {

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}
```

下図のようなところにでてきてちょっと便利。
![AddComponent.PNG](https://qiita-image-store.s3.amazonaws.com/0/17192/3fb67990-c7b4-de8a-70ba-34e1e9b8ab2f.png)
![AddComponent2.PNG](https://qiita-image-store.s3.amazonaws.com/0/17192/95ecd04a-e82c-f43a-dbe0-dc1febaf6dde.png)
初心者におすすめ Vim 設定・プラグイン

私もエンジニアになって半年がたったくらいでしょうか、段々業務に慣れてきました。
今日は日々業務で Vim を使っていくうえで、私が便利だなって思ったプラグインやコマンド、設定を紹介します。

vim の設定ファイル(.vimrc)ですが、基本的な設定はたくさん記事があるのでそちらを
参考にしてください <投げやり

# swapファイルを生成しない 
```ruby
set noswapfile
```

これはswapファイルの生成を作らないようにしてくれます！
tmuxを使って複数ファイルを同時に開いて編集したりするんですが、
すでに開いているやつを間違えてもう一度開いてしまう度にswapファイルが作られて
開くだの復元するだ問い詰められるという面倒くさい事もこれでなくなります。
まぁ、ミスった場合の保険がなくなりますが

# endwise.vim
```ruby
NeoBundle 'tpope/vim-endwise'
```

これは、doブロック や def、if文などを作成するときに end を自動で入力してくれたりしてくれます。
if を入力して Enter を押すと end が自動的に入力されます。
if文等だけでなく {} や () など { を入力するだけで } を自動入力してくれます。
[Vim で Ruby の def end とかを自動入力する vim-endwise を vim-smartinput で実装してみた](http://cohama.hateblo.jp/entry/2013/11/08/013136)

# rails.vim
```ruby
NeoBundle 'tpope/vim-rails'
```

このプラグインは様々な機能があるんですが、私は全部把握してません()
数ある機能の中で一番使っているのが コントローラーとビューの切り替えです

:R で controller と対応する view の入れ替え
gf で 現在のカーソル位置にあるモデルに飛ぶ

上記以外にもたくさん機能があるのですが、いっぱいあるので省略です。
[Rails.vim の使い方メモ](http://u16suzu.hatenablog.com/entry/20111117/1321561015)

# Syntastic
```ruby
NeoBundle 'scrooloose/syntastic.git'
```

これは Ruby の構文エラーをチェックしてくれる便利なもんです
インデントが足りないよとか、古い書き方してるよとか、むっちゃ指摘してくれます。
Syntastic に怒られないようにするだけでも綺麗なコードになる(かも)
指摘内容は英語で書かれているので頑張って読んでください...
[syntasticを利用してVimを高機能IDE的に使う+.vimrc晒し](http://qiita.com/foloinfo/items/662007fcf4f802a19f3a)

# ctags

どんなものかというと、定義元クラス・メソッドにジャンプしてくれる機能です。
Controller で Member が出てきたときに Member にカーソルを合わせて Ctrl + ] を押すと Member が定義されたファイルに飛ぶことができます。
なので、コードをたどる際にこれどこから出てきたんだとかどこで設定してあるんだなどが簡単にわかりやすいです。
別にジャンプできるプラグインなら ctag じゃなくても何でもいいです。
導入する際には物によって設定が必要で大変かもしれませんが、必須級なので頑張りましょう！
[rubyで定義元メソッドへジャンプ ctags+vim-tags](http://tamata78.hatenablog.com/entry/2015/07/16/211555)

# 以上

いくつかご紹介しました。
私もまだまだひよっこで全然使いこなせていないですが、あると便利(かも)なのでぜひ！
プロエンジニアの方には全然参考にならないですが、エンジニアになりたての方など、
コードを読み解くの大変だったり、構文エラーに気づかなかったりなどすることもあると思うので、参考にしてみてください。