Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

instance_eval()を使うとブロック内でメソッドを呼び出せる

> str = "test"

という文字列があるとします。
これにinstance_evalメソッドをブロック付きで実行すると、追加の文字列を作れます。

> str.instance_eval {|e| "hogehoge %s" % [e]}
=> "hogehoge test"

この程度だと旨味がありませんね。
では、これならどうでしょう??

> str.instance_eval {"hogehoge %s" % [reverse]}
=> "hogehoge tset"

文字列をひっくり返すreverseメソッドを使って愉快な事ができます。
挙げ句の果てに、コレ、インスタンスに対して複数のメソッドまで定義できます。

> puts str.instance_eval { " self\t\t:%s\n reverse\t:%s\n upcase\t\t:%s\n howmany\'t\'\t:%i\n" % [self, reverse, upcase, count('t') ] }
 self		:test
 reverse	:tset
 upcase		:TEST
 howmany't'	:2
=> nil

もうわけがわかりません

自身を返すことも当然できます。
ブロック変数を使うか、selfをつかえばおkです

> str.instance_eval {|e| "hogehoge %s %s %s" % [e, reverse, upcase]}
=> "hogehoge test tset TEST"

> str.instance_eval {"hogehoge %s %s %s" % [self, reverse, upcase]}
=> "hogehoge test tset TEST"

参考もと

Rubyベストプラクティス -プロフェッショナルによるコードとテクニック

Rubyベストプラクティス -プロフェッショナルによるコードとテクニック