Как я могу определить динамически константу внутри динамически определенного подкласса динамически определенного класса - PullRequest
0 голосов
/ 23 июня 2018

Как я могу динамически определить константу внутри динамически определенного подкласса динамически определенного класса, как это, но без ошибки NameError: uninitialized constant Foo::Bar:

Object.const_set('Foo',Class.new) {|klass| klass.const_set('Bar', Class.new){|subklass| subklass.const_set(:YEP,'Yep!')}}

, чтобы получить:

> Foo::Bar::YEP #=> 'Yep!'

Ответы [ 2 ]

0 голосов
/ 23 июня 2018

Следующее эквивалентно ответу @ SimpleLime, просто выраженному по-разному.

def make_class(name, parent=Object)
  Object.const_set(name, Class.new(parent))
end

foo = make_class('Foo')
  #=> Foo
bar = make_class('Bar', foo)
  #=> Bar
bar.superclass
  #=> Foo
bar.const_set('YEP', 'Yep!')
Bar::YEP
  #=> "Yep!"
bar::YEP
  #=> "Yep!"

При желании переменные могут быть разложены на множители.

make_class('Bar', make_class('Foo')).const_set('YEP', 'Yep!')
Bar::YEP
  # => "Yep!"

См. Класс:: new и Module # const_set

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

foo = Class.new
bar = Class.new(foo)
bar.const_set('YEP', 'Yep!')
bar::YEP
  #=> "Yep!"

иссылаться на классы по переменным foo и bar.

0 голосов
/ 23 июня 2018

Когда вы заключаете параметры метода в круглые скобки, блок фигурных скобок применяется к вызову метода, а не к последнему параметру в списке.Таким образом, эти { |klass| ... } передаются Object.const_set, а не Class.new.Если вы переместите эту закрывающую скобку после блока, он будет работать, потому что блоки передаются в Class.new вместо Object.const_set:

Object.const_set('Foo',Class.new { |klass|
  klass.const_set('Bar', Class.new { |subklass|
    subklass.const_set(:YEP,'Yep!')
  })
})
Foo::Bar::YEP # => "Yep!"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...