Подтвердить что ты не робот

Использование ключевого слова ruby?

из того, что я понимаю в ключе self, он просто ссылается на текущий экземпляр класса. Разве это не поведение по умолчанию во все времена? Например, не

self.var_one = method(args) эквивалентно просто var_one = method(args)?

Если да, то что такое использование self?

4b9b3361

Ответ 1

В большинстве случаев self.foo действительно избыточно, потому что вы можете просто написать foo для того же эффекта, но в этом случае это не так, и требуется self.

var_one = method(args) создаст локальную переменную с именем var_one, она не вызовет никакого метода и не сделает что-либо еще для self.

self.var_one = method(args) вызовет метод var_one= на self с аргументом method(args).

Другим случаем, когда использование self не является необязательным, было бы, если вы хотите передать его в качестве аргумента в метод, т.е. some_method(self) - вы не можете сделать это без ключевого слова self.

Ответ 2

Существует несколько важных применений, большинство из которых в основном устраняют неоднозначность между методами экземпляра, методами класса и переменными.

Во-первых, это лучший способ определить методы класса. 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, но часто полезно продолжать и использовать его, чтобы впоследствии не создавать непреднамеренные конфликты имен. Иногда они могут создавать ошибки, которые очень трудно найти. В конце концов, это часто вопрос личного стиля.


Обновление: как отмечено в комментариях, еще одна важная вещь:

В классе, если у вас есть такой метод:

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 нуждается в помощи для различения вызовов методов и локальных переменных или назначения локальных переменных.

Надеюсь, это имеет смысл!

Ответ 3

здесь пример использования:

def run miles
  self.miles = miles
end

В этом случае самопомощь поможет. в большинстве случаев self является избыточным.

Ответ 4

Другим использованием self является объявление методов класса (аналогично статическим методам в Java).

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

При этом вы также могли бы использовать def foo.bar для сигнатуры метода.