class_eval
на самом деле не имеет ничего общего с class << className
.
A.class_eval do
...
end
эквивалентно
class A
...
end
с некоторыми отличиями. class_eval использует блок (или строку, но игнорирует ее на данный момент), что означает, что он закрывается над содержащей лексическую область видимости. Другими словами, вы можете использовать локальные переменные из окружающей области видимости. Блок общего класса представляет совершенно новую область применения. Точно так же вы можете создать блок и передать его множеству различных class_eval, и тело блока будет выполнено в контексте класса, для которого вы вызываете class_eval.
class << className
открывает одноэлементный класс className
, позволяя вам определять методы класса.
class << A
def foo
...
end
end
Так же, как
def A.foo
...
end
Обратите внимание, что они являются методами класса oly, если A оказывается классом (почти) все объекты в ruby имеют одноэлементные классы, и вы можете определить методы для них, используя любой из этих двух синтаксисов. Преимущество class << obj
в основном в том случае, если вы определяете много одноэлементных методов за один раз.