【Ruby】パーフェクトRuby 学習感想文 ~第10章
それでは10章を読んでいきます。
(参考・経緯など)
パーフェクトRuby 学習感想文 ~はじめに
P310 Object#sendメソッドは、インスタンス変数でも使える
(注)---------------------------------------------\
以下の記事はインスタンス変数について理解に誤りがあります。
正しい理解はこちら⇒http://sekai.hateblo.jp/entry/2013/08/21/073111
ただし、この記事はあくまで「パーフェクトRubyをよんだ読者の軌跡」を記録しているので、以下は修正しません。
\--------------------------------------------------
class MailSender attr_reader :from def initialize(from) @from = from end def send(to) "send mail: #{to}" end end ms = MailSender.new('tanaka') p ms.send 'hoge' ←"send mail: hoge" p ms.__send__ :from ←"tanaka" p ms.instance_variable_get :@from ←"tanaka"
最初はこの「ms.__send__ :from」ってところ、誤植かと思いました。
だって、fromメソッドなんてないよ?
「p ms.instance_variable_get :@from」は自分で追加した一行。
インスタンス変数の場合は、instance_variable_get と __send__ が同じ挙動なんだ。
本にも
Object#send はメソッドの可視性に拘らずメソッドを呼ぶことが可能です
と書いている。
例でコードを書くなら、インスタンス変数の場合もsendメソッドが使えるよ、
と一言欲しかったなあ。
ここらへん、したり顔で「インスタンス変数もメソッドの一部、
つまりはオブジェクトと考えられるわけです。」とか出てきそう。
いや知らんけど(今は)。
うーん。Ruby。奥深いぞ。
自分はまだまだ、オブジェクト指向の理解が足りてないなー。
P330 初めての問題
what_methods っていう面白いgem(ってなんだ?まだ出てきてないぞ)があるよ。
ここまで読んだ人なら分かるから、実装してみてね。
と書いてある。
はい。
やります。
当然(?)require の仕方、installの仕方が分からず実行できない。
本家のソースがgithub上で公開されているので、それを答えにする事にする。
https://github.com/BMorearty/what_methods/blob/master/lib/what_methods.rb
■作ったコード ※ざっくり作ってます
class Object def what?(after, *args) WhatMethods.find(self, after, *args) end end class WhatMethods def self.find(before, after, *args) res = before.methods. select {|name| before.method(name).arity.abs <= args.size}. select {|name| begin before.clone.method(name).call(*args) == after; rescue Object; end } end end p "jjjj".what?("jjj") p "jjj".what?("JJJ")
■実行結果
jjjj[:chop, :chop!] jjj[:upcase, :swapcase, :upcase!, :swapcase!]
初めてRubyコードを書いて学んだこと
- Arrayクラスのselect メソッドは便利。
- インデントのつけ方が微妙になっちゃう。
- rescue Object ってずるい。真面目に考えて解答見たら、この書き方だった。
- Objectクラスを上書きできるのが、新鮮。
- 出力結果にレシーバ文字列が表示されているのはString#display メソッドが実行されているから。
- 解答の元のコードは、可変長引数の場合が全く考慮されてないのが心配だ(arityメソッドが負の時の分岐がない)
メタプログラミング、けっこう分かりやすいかもー。