self - это специальная переменная, которая указывает на объект, который «владеет» текущим исполняемым кодом. Ruby везде использует self:
- Для переменных экземпляра: @ myvar
- Для поиска метода и константы
- При определении методов, классов и модулей.
Внутри метода экземпляра
В приведенном ниже коде отражается метод экземпляра. Он принадлежит объекту, который мы создали через Event.new. Таким образом, self указывает на этот объект.
class Event
def reflect
self
end
end
g = Event.new
g.reflect == g # => true
Внутри метода класса
В этом примере отражение является методом класса Ghost. С помощью методов класса сам класс «владеет» методом. self указывает на класс.
class Event
def self.reflect
self
end
end
Event.reflect == Event # => true
Он работает так же с методами "class" внутри модулей. Например:
module Event
def self.reflect
self
end
end
Event.reflect == Event # => true
Помните, что классы и модули рассматриваются как объекты в Ruby. Так что это поведение ничем не отличается от поведения метода экземпляра, которое мы видели в первом примере.
Внутри определения класса или модуля
Одна особенность Ruby это делает его таким подходящим для фреймворков, как Rails, что вы можете выполнять произвольный код внутри определений классов и модулей. Когда вы помещаете код в определение класса / модуля, он работает так же, как любой другой код Ruby. Единственная реальная разница - это значение self.
Как вы можете видеть ниже, self указывает на класс или модуль, который находится в процессе определения.
class Event
self == Event # => true
end
module Join
self == Join # => true
end
Inside методы mixin
Смешанные методы ведут себя как обычные методы экземпляра или класса, когда дело касается себя. Это имеет смысл. В противном случае миксин не сможет взаимодействовать с классом, в который вы его смешали.
Методы экземпляра
Несмотря на то, что метод отражает, как определено в модуле, его self - это экземпляр класса, в который он был смешан.
module Reflection
def reflect
self
end
end
class Event
include Reflection
end
g = Event.new
g.reflect == g # => true
Методы класса
Когда мы расширяем класс для смешивания в методах класса, self ведет себя точно так же это происходит в обычных методах классов.
module Reflection
def reflect
self
end
end
class Event
extend Reflection
end
Event.reflect == Event # => true
Внутри метакласса
Скорее всего, вы видели этот популярный ярлык для одновременного определения множества методов класса.
class Event
class << self
def method1
end
def method2
end
end
end
Синтаксис класса << foo на самом деле довольно интересен. Он позволяет получить доступ к метаклассу объекта - который также называется «синглтон-класс» или «собственный класс». Я планирую более подробно осветить метаклассы в следующем посте. Но сейчас вам просто нужно знать, что в метаклассе Ruby хранятся методы, уникальные для конкретного c объекта. </p>
Если вы обращаетесь к себе изнутри блока << foo класса, вы получить метакласс. </p>
class << "test"
puts self.inspect
end
# => #<Class:#<String:0x007f8de283bd88>
За пределами любого класса
Если вы запускаете код вне какого-либо класса, Ruby по-прежнему обеспечивает self. Он указывает на «main», который является экземпляром Object:
puts self.inspect # => main