Подтвердить что ты не робот

Строка Ruby для имени класса

Я пытаюсь создать новый класс, который будет наследоваться от ActiveRecord::Base класс должен динамически генерироваться из строки

"general_systems".camelize.singularize = Class.new < ActiveRecord::Base

Однако я продолжаю получать ошибку:

undefined method 'singularize=' for "GeneralSystems":String

Я также пытался constantize строку

>> foo = "general_systems".camelize.singularize
=> "GeneralSystem"
>> foo.constantize
NameError: uninitialized constant GeneralSystem
    from /var/lib/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/inflector/methods.rb:124:in 'block in constantize'
    from /var/lib/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/inflector/methods.rb:123:in 'each'
    from /var/lib/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/inflector/methods.rb:123:in 'constantize'
    from /var/lib/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/core_ext/string/inflections.rb:43:in 'constantize'
    from (irb):4
    from /usr/bin/irb:12:in '<main>'
>> foo.constantize = Class.new
NoMethodError: undefined method 'constantize=' for "GeneralSystem":String
    from (irb):5
    from /usr/bin/irb:12:in '<main>'

Любая помощь будет принята с благодарностью.

4b9b3361

Ответ 1

Если вы используете Rails, он предоставляет метод под названием #constantize, который будет работать:

irb(main):017:0> Object.const_get 'House::Owns'
NameError: wrong constant name House::Owns

'House::Owns'.constantize
=> House::Owns

Ответ 2

Что-то вроде этого?

>> Object.const_set("general_systems".classify, Class.new)
=> GeneralSystem
>> GeneralSystem.new
=> #<GeneralSystem:0x105b0f738>

Ответ 3

klazz = Class.new(ActiveRecord::Base) do
  def do_something_fun(param1)
    param1.have_fun!
  end
end

klazz_name = "general_systems".singularize.classify
Object.const_set(klazz_name, klazz)

Ответ 4

Посмотрите на этот пример из "Книги Руби", включенный в программу установки Ruby 1.9.

puts("What shall we call this class?> ")
className = gets.strip().capitalize()
Object.const_set(className,Class.new)
puts("I'll give it a method called > 'myname'" ) 
className = Object.const_get(className)
className::module_eval{
  define_method(:myname){ 
    puts("The name of my class is '#{self.class}'" ) 
 } }
 x = className.new x.myname

Ответ 5

Если ваша строка содержит пространство имен, вы можете использовать:

require 'rubygems'
require 'active_support/inflector'
parent=String # using String to get a self contained example
# require 'active_record'   # uncomment for ActiveRecord::Base as parent class
# parent=ActiveRecord::Base # uncomment for ActiveRecord::Base as parent class
namespace = 'A::B::general_systems'.split('::') 
class_name = namespace.pop 
namespace = namespace.inject(Object) do |mod, name|
  if mod.constants.collect{|sym| sym.to_s}.include? name.classify
    mod.const_get name.classify
  else
    mod.const_set name.classify, Module.new
  end
end

klass = if namespace.constants.include? class_name.classify
  namespace.const_get class_name.classify
else
  namespace.const_set class_name.classify, Class.new(parent)
end

object = klass.allocate # allocate new object of klass
object.send :initialize # initialize object
object.class
object.class.superclass

Ответ 6

Дано:

class Banana
end

Вы можете получить класс в обычном Ruby с помощью:

Object.const_get 'Banana'
=> Banana

или если вы используете Rails:

'Banana'.constantize
=> Banana

Ответ 7

попробовать

>> "general_systems".classify
=> "GeneralSystem"