Где определены методы и операторы, которые позволяют делать "class << self; def foo; end; end" внутри определения класса? - PullRequest
3 голосов
/ 24 марта 2009

Как это объяснить? Могу ли я заменить себя другим объектом?

Ответы [ 4 ]

10 голосов
/ 24 марта 2009

Этот синтаксис используется в ruby ​​для доступа к метаклассу объекта или классу синглтона. Метакласс используется для хранения методов для отдельного объекта.

obj = # whatever...
class <<obj
  # here, self is defined as obj's metaclass
  # so foo will be an instance method of obj's metaclass
  # meaning that we can call obj.foo
  def foo
    # ...
  end
end
# this is equivalent to the above
def obj.foo
  # ...
end 

Это основная часть языка, которая не определена ни в одной библиотеке.

4 голосов
/ 24 марта 2009

Также см. Объяснение метаклассов _why:

http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

Кроме того, что касается «себя» и его замены, я видел упомянутое в нескольких других местах - мне сложно придумать хороший вариант использования этой функции, хотя это наверняка смутило бы меня. Возможно, есть один. В любом случае это неверный синтаксис в Ruby, чтобы попытаться изменить значение «self»: ​​

>> self = Object.new
SyntaxError: compile error
(irb):1: Can't change the value of self
self = Object.new
     ^
from (irb):1
from :0

В Ruby и во всех других языках, в которых есть это понятие «я» или «это», оно используется как указатель на «здесь», как, например, текущий объект, класс, метакласс или любой другой объект. представляет то, что означает «здесь». Поскольку Ruby интерпретируется построчно, «self» означает включающий объект, когда компилятор встречает это ключевое слово.

class Array
  self # Means Array class (which is an object, actually)

  def self.class_method
    self # still means Array class, since you're in a class method
  end

  def hello
    self # Means the current instance of Array
  end

  class << self
    self # Means the metaclass (or "eigenclass") of the Array
  end
end
2 голосов
/ 24 марта 2009

Этот синтаксис используется для добавления методов класса, которые вы вызываете для класса, а не для конкретного экземпляра этого класса.

Например:

  class Foo
    class << self
      def do_foo
        # something useful
      end
    end
  end

Теперь вы можете вызывать Foo.do_foo, даже если у вас нет объекта типа Foo.

Это эквивалентно:

  class Foo
    def self.do_foo
      # something useful
    end
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...