Jak używać słowa kluczowego SELF Ruby

Z tego, co rozumiem o self, odnosi się do bieżącej instancji klasy.

Czy to nie jest domyślne zachowanie przez cały czas? Na przykład isn ' t

self.var_one = method(args)

Odpowiednik

var_one = method(args) 

Jeśli tak, to jaki jest pożytek z self?

Author: the Tin Man, 2011-07-12

4 answers

W większości przypadków {[0] } jest rzeczywiście zbędny, ponieważ można po prostu napisać foo dla tego samego efektu, ale w tym przypadku tak nie jest i self jest wymagane.

var_one = method(args) utworzy zmienną lokalną o nazwie var_one, nie wywoła żadnej metody ani nie zrobi nic innego z self.

self.var_one = method(args) wywoła metodę var_one= on self z argumentem method(args).

Innym przypadkiem, w którym użycie self nie jest opcjonalne, byłoby przekazanie go jako argumentu do metody, tzn. some_method(self) - ty nie można tego zrobić bez słowa kluczowego self.

 58
Author: sepp2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-12 18:59:44

Istnieje kilka ważnych zastosowań, z których większość służy do rozróżniania między metodami instancji, metodami klas i zmiennymi.

Po pierwsze, jest to najlepszy sposób na zdefiniowanie metod klasy:

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"

Również wewnątrz metod instancji self odnosi się do instancji, wewnątrz metod klasy odnosi się do klasy i zawsze może być używana do odróżniania od zmiennych lokalnych.

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

Tak więc, w końcu, można uniknąć używania self w wielu przypadkach, ale często pomocne jest użyj go, aby upewnić się, że nie przypadkowo tworzysz konfliktów nazw później. Czasami mogą one tworzyć błędy, które są bardzo trudne do znalezienia. W końcu to często kwestia osobistego stylu.


Jak zaznaczono w komentarzach, jeszcze jedna bardzo ważna rzecz:

W klasie, jeśli masz taką metodę:

def bar=(string)
  ...
end

I w innej metodzie wywołujesz:

def other_method
  bar = "abcd"
end

Nie wywoła Twojej metody bar=, tylko utworzy zmienną lokalną bar. Więc w w tym przypadku używasz self, aby powiedzieć Rubiemu, że nie tworzy zmiennej lokalnej:

def other_method
  self.bar = "abcd"
end

To samo dotyczy argumentu o nazwie metody:

def example
  ...
end

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

Jeśli skończyłeś self Ruby założyłby, że masz na myśli zmienną lokalną o tej samej nazwie.

Tak więc, ogólnie rzecz biorąc, self w nazwach metod jest używany do rozróżniania zmiennych klas I instancji, a wszędzie indziej używasz go, gdy Ruby potrzebuje pomocy w rozróżnianiu wywołań metod i lokalnych zmienne lub przypisanie zmiennych lokalnych.

Mam nadzieję, że to ma sens.
 122
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-04 00:14:59

Innym zastosowaniem self jest deklarowanie metod klasy (podobnych do metod statycznych w Javie).

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

To powiedziawszy, mogłeś również użyć def foo.bar zamiast podpisu metody.

 4
Author: brayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-12 20:11:01

Oto przykład:

def run miles
  self.miles = miles
end

W tym przypadku self pomoże. W większości przypadków self jest zbędny.

 4
Author: Sohan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-04 00:15:33