背景:
レシーバとは、A.medhod(B)のAのことです。
メソッドの前のレシーバがないように見える場合があります。例えば、以下のような場合です。
class ClassA
def say
puts instance_of? String #false
puts instance_of? ClassA #true
end
end
ClassA.new.say
#false
#true
instance_of? は
【Ruby】is_a? と instance_of? の違い
の説明にも書いたように、
A.instance_of? B
とあるときに、AはBのインスタンスであるというものなのですが、上記の例の場合A.
がないですよね。
考え方
結論としては、上記のinstance_of?の前にはClassAのインスタンスがついています。
同じクラスや継承元クラスやインクルードしたモジュールのメソッドを参照する場合はメソッドの前にインスタンスをつける必要がないです(自動的についていると考える)。
追記:「レシーバーをあらわに書かないメソッド呼び出しでは,self がレシーバーとなる,というルールがあります。」というコメントをいただきましたが、こちらの考え方の方がわかりやすいと思います。
例えば、以下のような場合がありますが、
class ClassB
def say_b
say_b2
end
def say_b2
puts "bbb"
end
end
ClassB.new.say_b
# bbb
これはほとんど違和感ありませんよね?
同じクラスのメソッドは他のメソッドからレシーバを書かず(というか書けない)に実行することができます。
これと同様に先のinstance_of?メソッドも実際はスーパークラスのObjectクラスのメソッドです(厳密にいうとObjectクラスがインクルードしてるKernelモジュールのメソッドのようです)。
ClassA.new.method(:instance_of?).owner
=> Kernel
違和感を感じた原因
おそらく、最初のinstance_of?がいきなり出てきたところで、違和感を感じたのはinstance_of?メソッドとClassAの関連が見えなかったからと思われます。
確認方法
レシーバを確認する方法もあります。
method(:メソッド).receiver
で出力できます。
class ClassB
def say_b
say_b2
puts method(:say_b2).receiver
end
def say_b2
puts "bbb"
end
end
ClassB.new.say_b
# bbb
# #<ClassB:0x00007ff34d8a0550>
say_b2 のレシーバがClassBのインスタンスであることが確認できます。
実は、method(:say_b2)の前にもClassBのインスタンスが既についてしまっているのですが。