【Ruby】パーフェクトRuby 学習感想文 ~第9章
それでは9章を読んでいきます。
(参考・経緯など)
パーフェクトRuby 学習感想文 ~はじめに
初めての突っ込みゼロの章。おめでとうございます。
調子にのってすみません・・。怒らないでください
感想
Procオブジェクトが面白い。
レシーバーなのにメソッド定義も持っている、って感じ?
double = Proc.new{|x| x*2} p double.(1) ←2
トップレベルメソッドの実行レシーバーは何?
ちょっとはまった。
当然実行できる↓
def kore(x) x * 3 end p kore(1) #3
self.kore にするとエラーになる↓
def kore(x) x * 3 end p self.kore(1) #エラー。`<main>': private method `kore' called for main:Object
うーん。Objectクラスインスタンスではkoreメソッドを見に行けませんってことかな。private?
トップレベルのメソッドは暗黙的にselfがレシーバーだと思ってたのに。
なら何がレシーバーなんだ?
トップレベルself のクラスを確認
def kore(x) x * 3 end p self.class.ancestors ←[Object, Kernel, BasicObject] p kore(1)
予想通りです。
トップレベルメソッド内のself のクラスを確認
def kore(x) p self.class.ancestors ←[Object, Kernel, BasicObject] x * 3 end p kore(1)
うーん? self.kore でもいけそうな気がするけど?
???
やっぱり「レシーバーが省略されるとselfがレシーバとなる」で正しいみたい。
なのになぜ self.kore(1) はエラーになるの?
正解:private メソッドはレシーバを省略するかたちでしか呼び出せない
P120に書いていました。
そうなのですね。だからself.kore() はエラーになったのですね。
なら、本当にkore がprivateメソッドとしてObjectクラスに登録されているか
しらべてみましょう。
Objectクラスのprivateメソッド一覧
def kore(x) x * 3 end p self.class.private_instance_methods p kore(1)
実行結果
↓
[:kore, :initialize_copy, :initialize_dup, :initialize_clone, … 3
おー。koreメソッドがあるぞー。
つまりkore メソッドは、selfオブジェクトの特異メソッドってことか。
P245にこう書いてある↓
特異メソッドを定義した際に、 その特異メソッドが定義されるクラスが特異クラスです。
つまり、selfはObjectクラスのインスタンスだと思っていたけど、正確には
「selfはObject特異クラスのインスタンス」って事か?確認してみよう。
selfはObject特異クラスのインスタンス
def kore(x) x * 3 end p self.class.method_defined? :kore ←false p self.singleton_class.method_defined? :kore ←false p self.singleton_class.private_method_defined? :kore ←true p self.singleton_class ←#<Class:#<Object:0x4aef98>>
なるほどー。