Может ли кто-нибудь объяснить мне, что важно добавить self
к определению метода? Это похоже на ключевое слово this
в java?
Что означает имя `self.function`?
Ответ 1
В отличие от других языков, Ruby не имеет методов класса, но он имеет методы singleton, привязанные к определенному объекту.
cat = String.new("cat")
def cat.speak
'miaow'
end
cat.speak #=> "miaow"
cat.singleton_methods #=> ["speak"]
def cat.speak
создал метод singleton, прикрепленный к объекту cat.
Когда вы пишете class A
, это эквивалентно A = Class.new
:
A = Class.new
def A.speak
"I'm class A"
end
A.speak #=> "I'm class A"
A.singleton_methods #=> ["speak"]
def A.speak
создал метод singleton, прикрепленный к объекту A. Мы используем его как метод класса класса A.
Когда вы пишете
class A
def self.c_method
'in A#c_method'
end
end
создается экземпляр класса (*). Внутри определения класса Ruby устанавливает себя в этот новый экземпляр класса, который был назначен константе A. Таким образом, def self.c_method
эквивалентно def cat.speak
, то есть вы определяете метод singleton, привязанный к объекту self, который в настоящее время является классом А.
Теперь класс A имеет два одноэлементных метода, которые мы обычно называем методами класса.
A.singleton_methods
=> ["c_method", "speak"]
(*) технически, в этом случае, когда A уже был создан A = Class.new, class A
снова открывает существующий класс. Вот почему у нас в конце есть два метода синглтон. Но в обычном случае, когда это первое определение класса, это означает Class.new.
Ответ 2
В ruby self несколько похож на this
в java, но когда дело доходит до классов, это больше похоже на ключевое слово static
в java. Краткий пример:
class A
# class method
def self.c_method
true
end
# instance method
def i_method
true
end
end
A.c_method #=> true
A.i_method #=> failure
A.new.i_method #=> true
A.new.c_method #=> failure
Обновление: Разница между статическими методами в java и методами класса в ruby
Статические методы в Java имеют две различные функции, которые отличает их от методов экземпляра: a) они являются статическими, b) они не связаны с экземпляром. (IOW: они действительно не похожи на методы вообще, это просто процедуры.) В Ruby все методы являются динамическими, и все методы связаны с экземпляром. На самом деле, в отличие от Java, где есть три разных типа "методов" (методы экземпляра, статические методы и конструкторы), в Ruby: методы экземпляров есть только один вид. Итак, нет: статические методы в Java полностью не похожи на методы в Ruby. - Jörg W Mittag 1 час назад
Ответ 3
При объявлении метода self
объявление является объявлением класса/модуля, поэтому вы фактически определяете метод класса. Для клиента это работает аналогично static
методу в Java. Клиент будет вызывать метод класса вместо экземпляра: MyClass.method
Здесь вы можете найти более подробную информацию о методах класса и экземпляра.
РЕДАКТИРОВАТЬ: Хотя ключевое слово self
сродни ключевому слову this
в java, эффекты использования self
для объявления метода класса аналогичны эффекту использования static
ключевого слова в java. Сходство в том, что статические методы в java, как и методы класса в ruby, доступны с использованием объекта класса iself вместо экземпляра класса.
Обратите внимание, что static
не означает противоположность динамического. Выбор имени для этого ключевого слова сомнителен (вероятно, унаследован от C) и скорее должен был называться perClass
или подобным, чтобы лучше отражать значение. Технический смысл заключается в том, что все static
члены существуют только один раз для каждого загрузчика классов.