Использование ключевого слова ruby?
из того, что я понимаю в ключе self
, он просто ссылается на текущий экземпляр класса. Разве это не поведение по умолчанию во все времена? Например, не
self.var_one = method(args)
эквивалентно просто var_one = method(args)
?
Если да, то что такое использование self?
Ответы
Ответ 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
для сигнатуры метода.