1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Ruby】メソッドの前のレシーバがない(ように見える)場合の考え方

Last updated at Posted at 2020-11-03

背景:

レシーバとは、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のインスタンスが既についてしまっているのですが。

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?