web-dev-qa-db-ja.com

Ruby selfキーワード?

selfキーワードについて理解していることから、それは単にクラスの現在のインスタンスを指します。とにかく、これは常にデフォルトの動作ではありませんか?たとえば、ではない

self.var_one = method(args)は、単にvar_one = method(args)と同等ですか?

もしそうなら、自己の使用は何ですか?

62
Ankit Soni

ほとんどの場合、同じ効果のためにfooを書くことができるので、_self.foo_は確かに冗長ですが、この場合はそうではなく、selfが必要です。

var_one = method(args)は、_var_one_というローカル変数を作成します。selfに対してメソッドを呼び出したり、他の処理を行ったりすることはありません。

self.var_one = method(args)は、引数method(args)を使用してselfのメソッド_var_one=_を呼び出します。

selfの使用がオプションではない別のケースは、メソッドに引数として渡す場合です。つまり、some_method(self)-selfキーワードなしではできません。

55
sepp2k

いくつかの重要な用途がありますが、そのほとんどは、基本的にインスタンスメソッド、クラスメソッド、および変数を明確にするためです。

まず、これはクラスメソッドを定義する最良の方法です。 IE:

class Foo
  def self.bar
    "class method bar"
  end

  def bar
    "instance method bar"
  end
end

Foo.bar  #returns "class method bar"

foo = Foo.new
foo.bar #returns "instance method bar"

また、インスタンスメソッド内ではselfはインスタンスを参照し、クラスメソッド内ではクラスを参照し、常にローカル変数と区別するために使用できます。

class Bar
  def self.foo
    "foo!"
  end

  def baz
    "baz!"
  end

  def self.success
    foo #looks for variable foo, doesn't find one, looks for class method foo, finds it, returns "foo!"
  end

  def self.fail
    baz #looks for variable baz, doesn't find one, looks for class method baz, doesn't find one, raises exception
  end

  def instance_success
    baz #looks for variable baz, doesn't find one, looks for instance method baz, finds it, returns "baz!"
  end

  def instance_fail
    foo #looks for variable foo, doesn't find one, looks for instance method foo, doesn't find one, raises exception
  end

  def local_variable
    baz = "is my favorite method"
    baz #looks for variable baz, finds it, returns "is my favorite method"
  end

  def disambiguate
    baz = " is my favorite method"
    self.baz + baz #looks for instance method baz, finds it, looks for local variable baz, finds it, returns "baz! is my favorite method"
  end
end

したがって、最終的には多くの場合selfの使用を避けることができますが、先に進んで、後で誤って名前の競合を作成しないようにするために使用すると便利です。時にはそれらは非常に見つけにくいバグを作成することがあります。結局、それはしばしば個人的なスタイルの問題です。


更新:コメントで述べたように、もう1つの本当に重要なこと:

クラスに、次のようなメソッドがある場合:

def bar=(string)
  ...
end

そして、別のメソッドで呼び出す:

def other_method
  bar = "abcd"
end

Bar =メソッドを呼び出すのではなく、ローカル変数barを作成します。そのため、この場合、selfを使用してRubyにローカル変数を作成しないように指示します。

def other_method
  self.bar = "abcd"
end

次のように、メソッドの名前で引数を取りたい場合も同じことが当てはまります。

def example
  ...
end

def other_thing(example)
  self.example(example)
end

自分自身をやめた場合、同じ名前のローカル変数を意味していると想定されます。

そのため、一般的に、メソッド名のselfはクラス変数とインスタンス変数を区別するために使用され、他のすべての場所でRubyメソッド呼び出しとローカル変数またはローカル変数の割り当てを区別するのに助けが必要です。

それが理にかなっていることを願っています!

117
Andrew

selfのもう1つの使用法は、クラスメソッドを宣言することです(Javaの静的メソッドに似ています)。

class foo
 def self.bar
  #do class related stuff here
 end
end

そうは言っても、def foo.bar代わりにメソッドシグネチャ用。

4
brayne

以下に使用例を示します。

def run miles
  self.miles = miles
end

この場合、selfが役立ちます。ほとんどの場合、自己は冗長です。

4
Sohan