Неявный контекст и собственные классы

Недавно я нашел интересную статью о неявных контекстах в Ruby, и мне показалось, что этот опыт довольно открывающий. Я понял, что в Ruby есть ссылка не только на self (получатель метода по умолчанию), но также к текущему классу (также известному как defaulte define или `klass').

Из статьи следует правильно предположить, что class определение устанавливает оба self и текущий класс для класса, который определяется; насколько мы рассматриваем нормальное определение метода (то есть, не используя точечный синтаксис для определения одноэлементных методов), в контексте определения метода с def, self ссылается на принимающий объект, а текущий класс не изменяется.

Причина, по которой я считаю безопасным не учитывать точечный синтаксис для определения, заключается в том, что Ruby также предлагает явный способ открытия собственного класса класса, и меня интересует понимание того, как управляются эти два неявных контекста при открытии собственного класса,

С помощью def с хорошо известным синтаксисом для открытия собственного класса:

class << A
  p self

  def foo
    # ...
  end
end

определяет foo как одноэлементный метод A т.е. метод экземпляра своего собственного класса (будь то A'). Этот код также печатает #<Class:A> поэтому правильно сказать, что << синтаксис устанавливает оба self и текущий класс A'?

2 ответа

Решение

Да, это фактически открывает блок под контролем A'. Также вы можете сказать, что он работает как class_eval из A'.

На самом деле, то, что вы написали, точно так же, как писать:

class A
  class << self
    def foo
      #...
    end
  end
end

синтаксис класса << self указывает, что блок определений будет следовать, и это будет идти прямо к собственному классу объекта, переданного <<. И да, я сказал Объект, а не Класс. Попробуйте это (при условии определения класса выше):

a = A.new
class << a
  def foo2
  end
end
a.singleton_methods
b = A.new
b.singleton_methods

это означает, что в этом случае вы определяете метод foo2 в собственном классе объекта a. Но это собственный класс самого объекта, а не класса. Таким образом, другие объекты того же класса не будут использовать это определение foo2.

Так что это значит? Ruby является (или претендует на звание) чистым ОО-языком. Все является объектом. Объект определенного вами класса является объектом. Определенный вами класс также является объектом. Типа Класс. Который наследует от объекта. В Ruby все объекты имеют собственный класс. На самом деле, определение "методов класса" - это просто интерпретация его концепции. "Методы класса" на самом деле не методы класса, а методы, определенные в собственном классе класса. Итак, когда вы вызываете "метод класса", вы действительно вызываете объектный метод. Этот объект просто является классом, который вы определили. Как вы определяете методы собственного класса? Именно класс << сам синтаксис. "Я" в этом контексте - это то, что вы передали в качестве аргумента классу <<.

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