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>'
どんな助けでも大歓迎です。
Railsを使用している場合は、機能する#constantize
というメソッドが提供されます。
irb(main):017:0> Object.const_get 'House::Owns'
NameError: wrong constant name House::Owns
'House::Owns'.constantize
=> House::Owns
このようなもの?
>> Object.const_set("general_systems".classify, Class.new)
=> GeneralSystem
>> GeneralSystem.new
=> #<GeneralSystem:0x105b0f738>
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)
Ruby 1.9インストーラに含まれている「The Book Of Ruby」からのこの例を見てください。
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
文字列に名前空間が含まれている場合は、次を使用できます。
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
与えられた:
class Banana
end
あなたはプレーンでクラスをフェッチすることができますRuby
Object.const_get 'Banana'
=> Banana
または、Railsを使用している場合:
'Banana'.constantize
=> Banana
試す
>> "general_systems".classify
=> "GeneralSystem"