サーチ…


常に暗黙の受信機があります

Rubyでは、すべてのメソッド呼び出しに常に暗黙のレシーバがあります。言語は、変数self格納されている現在の暗黙受信者への参照を保持します。 classmoduleなどの特定の言語キーワードは、 self指すものを変更します。これらの動作を理解することは、言語をマスターする上で非常に役立ちます。

たとえば、 irbを最初に開いたとき

irb(main):001:0> self
=> main

この場合、 mainオブジェクトは暗黙的な受信者です( mainについての詳細はhttp://stackoverflow.com/a/917842/417872を参照)。

defキーワードを使用して、暗黙の受信側でメソッドを定義できます。例えば:

irb(main):001:0> def foo(arg)
irb(main):002:1> arg.to_s
irb(main):003:1> end
=> :foo
irb(main):004:0> foo 1
=> "1"

これは、あなたのreplで実行されているメインオブジェクトのインスタンスに対するメソッドfooを定義しています。

ローカル変数はメソッド名の前に検索されるので、同じ名前のローカル変数を定義すると、参照がメソッド参照よりも優先されることに注意してください。前の例から引き続き:

irb(main):005:0> defined? foo
=> "method"
irb(main):006:0> foo = 1
=> 1
irb(main):007:0> defined? foo
=> "local-variable"
irb(main):008:0> foo
=> 1
irb(main):009:0> method :foo
=> #<Method: Object#foo>

methodメソッドはfooメソッドを見つけることができます。なぜなら、ローカル変数をチェックするのではなく、通常の参照fooがチェックするからです。

キーワードは暗黙の受信機を変更する

クラスまたはモジュールを定義すると、暗黙的な受信者はクラス自体への参照になります。例えば:

puts "I am #{self}"
class Example
  puts "I am #{self}"
end

上記のコードを実行すると印刷されます:

"I am main"
"I am Example"

いつ自己を使用するのですか?

ほとんどのRubyコードは暗黙的な受信機を利用しているので、Rubyを初めて使うプログラマはしばしばselfいつ使うのか混乱します。実用的な答えは、 selfが2つの主要な方法で使われていることです。

1.受信機を変更する。

通常、クラスまたはモジュール内部のdefの動作は、インスタンスメソッドを作成することです。自己を使ってクラスのメソッドを定義することができます。

class Foo
  def bar
    1
  end

  def self.bar
    2
  end
end

Foo.new.bar #=> 1
Foo.bar #=> 2

受信機の曖昧さを解消する

ローカル変数がメソッドと同じ名前を持つ場合、明確な受信者が曖昧さを排除する必要があります。

例:

class Example
  def foo
    1
  end

  def bar
    foo + 1
  end

  def baz(foo)
    self.foo + foo # self.foo is the method, foo is the local variable
  end

  def qux
    bar = 2
    self.bar + bar # self.bar is the method, bar is the local variable
  end 
end

Example.new.foo    #=> 1
Example.new.bar    #=> 2
Example.new.baz(2) #=> 3
Example.new.qux    #=> 4

曖昧さ回避を必要とする他の一般的なケースでは、等号で終わるメソッドが必要です。例えば:

class Example
  def foo=(input)
    @foo = input
  end

  def get_foo
    @foo
  end

  def bar(input)
    foo = input # will create a local variable
  end

  def baz(input)
    self.foo = input # will call the method
  end
end

e = Example.new
e.get_foo #=> nil
e.foo = 1
e.get_foo #=> 1
e.bar(2)
e.get_foo #=> 1
e.baz(2)
e.get_foo #=> 2


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow