Подтвердить что ты не робот

Что означает имя `self.function`?

Может ли кто-нибудь объяснить мне, что важно добавить self к определению метода? Это похоже на ключевое слово this в java?

4b9b3361

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