Использование ключевого слова ruby self?
из того, что я понимаю self
ключевое слово, он просто ссылается на текущий экземпляр класса. Разве это не поведение по умолчанию во все времена в любом случае? Например, не
self.var_one = method(args)
что эквивалентно var_one = method(args)
?
Если так, то зачем я?
4 ответа:
в большинстве случаев
self.foo
действительно избыточно, потому что вы можете просто написатьfoo
для того же эффекта, но в данном случае это не так и это.
var_one = method(args)
создать локальную переменную с именемvar_one
, он не будет вызывать какой-либо метод или делать что-либо еще, чтобыself
.
self.var_one = method(args)
вызывает методvar_one=
onself
С аргументомmethod(args)
.еще один случай, когда использование
self
не является необязательным было бы, если вы хотите передайте его в качестве аргумента методу, т. е.some_method(self)
- вы не можете сделать это безself
ключевое слово.
есть несколько важных применений, большинство из которых в основном для устранения неоднозначности между методами экземпляра, методами класса и переменными.
во-первых, это лучший способ определить методы класса. Т. е.:
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, это будет означать, что вы имели в виду локальную переменную с тем же именем.
таким образом, в общем случае self в именах методов используется для различения переменных класса и экземпляра, а также везде вы используете его, когда Ruby нужна помощь в различении между вызовами методов и локальными переменными или назначением локальной переменной.
Я надеюсь, что это имеет смысл!