В Ruby есть какие-либо связанные применения синтаксиса:класс << сам … конец

StackOverflow https://stackoverflow.com/questions/896480

Вопрос

class << self
attr_accessor :n, :totalX, :totalY
end

Приведенный выше синтаксис используется для определения переменных экземпляра класса.Но когда я думаю о том, что подразумевает синтаксис, для меня это не имеет никакого смысла, поэтому мне интересно, используется ли этот тип синтаксиса для каких-либо других типов определений.Моя путаница вот в чем:

class << self

Оператор добавления обычно означает «добавление того, что справа, к объекту слева».Но в контексте этого блока, как это означает «поместить содержимое этого блока в определение экземпляра класса, а не в экземпляр»?

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

class Point
  # Instance methods go here
  class << self
    # Class methods go here
  end
end
Это было полезно?

Решение

в Ruby вы можете повторно открыть существующие классы и добавить методы.То есть, вы можете сказать:

class Foo
  def bob
    return "hello from bob"
  end
end

эти методы сохраняются где-то во внутреннем словаре (возможно, в переменной экземпляра) Foo-class (который является просто экземпляром Class-класс и, следовательно, имеет переменные экземпляра)

Но самое удивительное то, что вы также можете добавлять методы в случаи существующих объектов

foo = Foo.new
foo2 = Foo.new

def foo.fred
  return "I am fred"
end


foo.fred  #=> "I am fred"
foo2.fred #=> NoMethodError

но Где на самом деле хранится этот метод?

Оказывается, Ruby за кулисами создает новый класс (иногда называемый одноэлементный класс, метакласс или собственный класс), который вставляется в иерархию наследования между тот Foo-класс и его экземпляр.

Таким образом, отношения наследования выглядят следующим образом:

foo < (eigenclass of foo) < Foo < Class

(если вы скажете foo.superclass, вы не увидите класс Singleton)

тот class << X-syntax — это способ добраться до этого специального класса, чтобы вы могли напрямую манипулировать им.Следующие блоки кода полностью эквивалентны:

def foo.bar
  return "xy"
end

# is exactly the same as

class << foo
  def bar
    return "xy"
  end
end

Итак, сходство между class Foo < Bar и class << Foo это не случайно, в обоих случаях имеет место наследование.

Думать о class << X как «открыть метакласс X»

В Ruby следует помнить, что классы сами по себе являются просто объектами.(Экземпляры класса Class), поэтому, если вы скажете:

class Foo
  class << self
    def k
      return "x"
    end
  end
end

(self связан с Foo в этом блоке кода), поэтому k является метод экземпляра собственного класса Foo, что делает его методом класса для Foo

все это более понятно объяснено в глава о классах Кирки (веб-версия, к сожалению, не содержит схем) и _whys Ясно видеть метаклассы

Другие советы

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

Хотя я признаю, что обозначения немного странные.

на самом деле сложно думать об этом как об операторе добавления.лучший способ взглянуть на это так же, как class Foo открывает класс Foo, то есть устанавливает «self» для объекта класса Foo, создавая его при необходимости, поэтому class << self открывает собственный класс текущего объекта self.обратите внимание, что это не ограничивается self - для любой панели объекта вы можете сказать class << bar, чтобы открыть собственный класс этого объекта.

class A
  def hello
    print "hello world"
  end
end

a = A.new
b = A.new

class << a
  def goodbye
    print "goodbye cruel world"
  end
end

a.hello
b.hello
a.goodbye
b.goodbye
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top