Что означает имя 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 члены существуют только один раз для каждого загрузчика классов.

Другие вопросы по тегам