Сначала определите класс Alpha
следующим образом.
class Alpha
puts "self in Alpha = #{self}"
def a
puts "self in a = #{self}"
end
def Alpha.b
puts "self in b = #{self}"
end
def Alpha.c
puts "self in c = #{self}"
end
end
# self in Alpha = Alpha
У нас есть один метод экземпляра, Alpha#a
и два метода класса, Alpha::b
и Alpha::b
. (Ссылка на методы экземпляра и класса в этом случае является соглашением Ruby, которое вы все время будете видеть в документах.)
Alpha.methods(false)
#=> [:c, :b]
Alpha.instance_methods(false)
#=> [:a]
См. Object :: method и Module # instance_methods , отмечая последствия включения аргумента false
.
Методы экземпляра вызываются в экземплярах класса; Методы класса вызываются в классе.
alpha = Alpha.new
#=> #<Alpha:0x000059c5ff614f08>
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
Alpha.b
# self in b = Alpha
Alpha.c
# self in c = Alpha
Что если мы попытаемся вызвать метод экземпляра в классе или метод класса в instance?
Alpha.a
#=> NoMethodError (undefined method `a' for Alpha:Class)
alpha.b
#=> NoMethodError (undefined method `b' for #<Alpha:0x000059c5ff614f08>)
Обычно мы пишем класс следующим образом.
class Alpha
def a
puts "self in a = #{self}"
end
def self.b
puts "self in b = #{self}"
end
def self.c
puts "self in c = #{self}"
end
end
В определении класса self
равно Alpha
, поэтому два способа написания класс эквивалентны. Единственная причина использования self
состоит в том, что если мы решим позже изменить имя класса на Beta
, нам не придется менять все Alpha
на Beta
в определениях методов класса.
Если мы хотим вызвать метод класса Alpha::b
из метода экземпляра Alpha#a
, мы должны изменить его следующим образом:
class Alpha
def a
puts "self in a = #{self}"
self.class.b
end
end
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
# self in b = Alpha
Здесь self.class
возвращает Alpha
, и мы знаем, что возвращает Alpha.b
.
Давайте изменим Alpha#a
еще раз и добавим метод второго экземпляра:
class Alpha
def a
puts "self in a = #{self}"
d
end
def d
puts "self in d = #{self}"
end
end
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
# self in d = #<Alpha:0x000059c5ff614f08>
Я мог бы написать:
def a
puts "self in a = #{self}"
self.d
end
но self.
не требуется и, как правило, не входит. Причина в том, что когда метод не имеет явного получателя, например, d
in:
def a
puts "self in a = #{self}"
d
end
self
становится получателем по умолчанию . Из вышеизложенного мы знаем, что в определении метода экземпляра self
равно экземпляру alpha
.