Как работает self?
Понял что метод self передает ссылку на сам себя, а вот в каких случаях использовать self а в каких нет я не понял...
3 Answers
Ruby - полностью объектно-ориентированный язык. В любой момент времени вы действуете в рамках какого-то объекта, даже если все выглядит так, что вы работаете вне объекта. В языке нет функций и процедур в привычном понимании, только методы, причем метод не может вызываться без получателя, т.е. объекта.
self - это ссылка на текущий объект. Для обращений к элементам интанс-объекта не обязательно указывать self, так как он подразумевается по умолчанию, но иногда он нужен. Например, при создании методов класса
class MyClass
def hello
p 'hello'
end
end
o = MyClass.new
o.hello
# MyClass.hello - ошибка
Однако
class MyClass
def self.hello
p 'hello'
end
end
MyClass.hello
o = MyClass.new
# o.hello - ошибка
Это не единственный случай, когда вы не сможете обойтись без self, однако чтобы всех их осветить потребуется небольшая книга. При работе с self главное помнить, что это ссылка на текущий объект и что такой объект всегда существует, даже когда вы работаете в корневой области видимости
self
=> main
- 19,454
- 29
- 48
- 139
-
А ещё
selfбывает необходим, чтобы вызвать у него сеттер, потому что без явногоself.можно случайно задать локальную переменную в текущей области видимости. – Jul 25 '16 at 15:05 -
"Функции и процедуры в привычном понимании" в Ruby есть: http://ruby-doc.org/core-2.2.0/UnboundMethod.html – Nakilon Jul 28 '16 at 09:33
-
@Nakilon странное у вас "привычное понимание".
UnboundMethodнельзя просто взять и вызвать, не привязав его к принимающему. И используются они в Ruby крайне редко и с довольно экзотическими целями вроде "пересадки методов" производительности ради. К функциям "в привычном понимании" ближе скорееProc, и то это всего лишь объект с методомcallи его синонимами. – Jul 28 '16 at 11:20
В другом ответе допущено несколько ошибок:
- Для объявления метода класса вы "сможете обойтись без self", если вместо
def self.напишетеdef MyClass. selfуказывает не всегда на "текущий объект", а скорей на объект, в контексте которого интерпретатор выполняет блок кода
Более близок к нужному ответу был @D-side. Если есть локальная переменная под тем же именем, что и метод, происходит затенение, и для подсказки интерпретатору, что мы хотим именно метод, можно приписать self. слева, но и тут есть другой способ -- приписать () справа. Здесь иллюстрации и методы борьбы с такой "проблемой": https://www.sitepoint.com/understanding-scope-in-ruby/
- 1,510
-
1Строго говоря, ваше сообщение не является ответом - это комментарий. Кроме того, у вас в комментарии допущено ряд ошибок: 1. Вы никогда не сможете вызывать непривязанный метод 2. def MyClass объявляет инстанс-методы, речь шла о методах класса. У вас ошибочное утверждение. 3. Утверждение ошибочно, блок вообще не имеет отношение к self. Убедиться в присутствии текущего объекта вы всегда можете обратившись к self. – cheops Jul 28 '16 at 05:20
-
Первый пункт действительно являлся лишь комментарием -- теперь я его перенес куда положено. Остальное является ответом, т.к. непосредственно отвечает на вопрос о том, когда и почему нужен
self. 2. проверил, ушло в.singleton_methods3. по ссылке же показан пример блока вclass_eval– Nakilon Jul 28 '16 at 09:42 -
@cheops 2. Скользкий момент! Смотря где. В контексте определения класса
selfэто класс. Внутри инстанс-методаselfэто текущий объект. В зависимости от того, где определить метод (хотя определять методы внутри методов это безумие, это возможно), получатся синглтон-методы у разных объектов :) – Jul 28 '16 at 10:13
Вставлю свои 5 копеек )
self в контексте метода
def some_method
self.some_other_method # это self в контексте метода, он обращается к объекту
# в отношении которого вызван метод someobj.some_method
# т.е. self == someobj
end
def self.some_class_method #это self в контексте класса он обращается к классу
# т.е определяется метод класса который можно вызывать
# используя имя класса SomeClass.some_class_method()
# т.е. self == SomeClass <br></i>
end
p.s я вижу это так ) Если не прав исправляйте..
- 1