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