Что означает имя def `self.function`?
Может ли кто-нибудь объяснить мне, каково значение добавления self
к определению метода? Это похоже на this
Ключевое слово в Java?
3 ответа
В отличие от других языков, Ruby не имеет методов класса, но имеет одноэлементные методы, привязанные к определенному объекту.
cat = String.new("cat")
def cat.speak
'miaow'
end
cat.speak #=> "miaow"
cat.singleton_methods #=> ["speak"]
def cat.speak
создал одноэлементный метод, прикрепленный к объекту 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
создал одноэлементный метод, прикрепленный к объекту А. Мы используем его для вызова метода класса класса А.
Когда ты пишешь
class A
def self.c_method
'in A#c_method'
end
end
Вы создаете экземпляр класса (*). Внутри определения класса Ruby устанавливает self для этого нового экземпляра Class, который был назначен константе A. Таким образом def self.c_method
эквивалентно def cat.speak
то есть вы определяете одноэлементный метод, присоединенный к объекту self, который в настоящее время является классом A.
Теперь у класса A есть два одноэлементных метода, которые мы обычно называем методами класса.
A.singleton_methods
=> ["c_method", "speak"]
(*) технически, в этом случае, когда A уже был создан A = Class.new, class A
вновь открывает существующий класс. Вот почему у нас есть два синглтон-метода в конце. Но в обычном случае, когда это первое определение класса, это означает Class.new.
В ruby self чем-то похоже на this
в Java, но когда дело доходит до классов его больше похоже на ключевое слово static
в Яве. Краткий пример:
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 имеют две отличные особенности, которые отличают их от методов экземпляра: а) они являются статическими, б) они не связаны с экземпляром. (IOW: они на самом деле совсем не похожи на методы, они просто процедуры.) В Ruby все методы являются динамическими, и все методы связаны с экземпляром. Фактически, в отличие от Java, где есть три различных типа "методов" (методы экземпляра, статические методы и конструкторы), в Ruby есть только один вид метода: методы экземпляра. Итак, нет: статические методы в Java совершенно не похожи на методы в Ruby. - Йорг Миттаг 1 час назад
При объявлении метода, self
объявления является объявлением класса / модуля, поэтому вы фактически определяете метод класса. Это как static
метод в Java. Вы бы вызвали метод класса вместо экземпляра: MyClass.method
Здесь вы можете найти более подробную информацию о методах класса и экземпляра.
РЕДАКТИРОВАТЬ: в то время как self
Ключевое слово сродни this
Ключевое слово в Java, эффекты использования self
для объявления метода класса аналогичны эффекту использования static
Ключевое слово в Java. Сходство в том, что статические методы в java, как и методы класса в ruby, доступны с использованием объекта класса iself вместо экземпляра класса.
Обратите внимание, что static
не означает противоположность динамической. Выбор имени для этого ключевого слова сомнителен (вероятно, унаследован от C) и скорее должен был быть назван perClass
или подобное, чтобы лучше отразить смысл. Технический смысл в том, что все static
члены существуют только один раз для каждого загрузчика классов.