Почему не могут быть классы внутри методов в Ruby?
Могу ли я создавать классы Ruby в телах функций?
Кажется, я получаю ошибку, которая говорит мне, что она не разрешена, но я думаю, что это должно быть, поскольку классы тоже являются объектами здесь.
class A
def method
class B
end
end
end
Это происходит с ошибкой определения класса внутри тела метода.
Если мы не можем, почему мы не можем создавать классы внутри методов?
Ответы
Ответ 1
class A
def method
self.class.const_set :B, Class.new {
def foo
'bar'
end
}
end
end
A.new.method
A::B.new.foo # => 'bar'
Однако почему вы хотите назначить константу внутри метода? Это не имеет смысла: константы постоянны, их можно назначать только один раз, что означает, что вы можете запускать свой метод только один раз. Тогда, почему вы вообще пишете метод, если он когда-либо будет запускаться один раз, в любом случае?
Ответ 2
вы можете создавать классы, но вы не можете назначать константы внутри метода.
этот пример работает:
class A
def a
b = Class.new
def b.xxx
"XXX"
end
b
end
end
a = A.new.a
p a # #<Class:0x7fa74fe6cc58>
p a.xxx # "XXX"
Ответ 3
Вы можете создавать классы из методов и назначать их константе, как в следующем
class A
def create_class class_name
new_class = Class.new
new_class.send :define_method, :speak do
"Hi, There"
end
Object.const_set class_name, new_class
end
end
A.new.create_class "Harry"
h = Harry.new
puts h.speak # responds => "Hi, There"
потому что имя класса, как в String, является константой в рубине, в отличие от многих других языков.
Ответ 4
Вопрос о создании классов, но в комментарии вы говорите о создании анонимных объектов. Не то же самое.
Если вам нужен анонимный объект, вы всегда можете сделать Object.new
. Если вам нужен простой структурированный контейнер, вы должны взглянуть на класс Struct
. С его помощью вы можете сделать что-то вроде:
def foo
anon_obj = Struct.new(:prop1, :prop2).new
anon_obj.prop1 = 123
anon_obj.prop2 = 'bar'
return anon_obj
end
BTW, Ruby - строго типизированный язык. Но это тоже динамически типизируется, и вы не можете ожидать, что он будет вести себя как статический тип.