1. ホーム
  2. ruby

動的なクラス定義 WITH a Class Name

2023-07-30 06:20:55

質問

Rubyのクラスを名前付きで動的に定義するには?

私はクラスを動的に作成する方法を知っています を使わずに のようなものを使って名前を付ける方法を知っています。

dynamic_class = Class.new do
  def method1
  end
end

しかし、クラス名を指定することはできません。動的にクラスを作成したい という名前にしたい。

以下は私がやりたいことの例ですが、もちろん実際にはうまくいきません。

(クラスのインスタンスを作成しているのではなく、クラス定義を作成していることに注意してください)

class TestEval
  def method1
    puts "name: #{self.name}"
  end
end

class_name = "TestEval"
dummy = eval("#{class_name}")

puts "dummy: #{dummy}"

dynamic_name = "TestEval2"
class_string = """
class #{dynamic_name}
  def method1
  end
end
"""
dummy2 = eval(class_string)
puts "dummy2: #{dummy2}" # doesn't work

実際の出力です。

dummy: TestEval
dummy2: 

希望する出力

dummy: TestEval
dummy2: TestEval2

======================================================

回答 sepp2kの方法による完全な動的解法です。

dynamic_name = "TestEval2"

Object.const_set(dynamic_name, Class.new) # If inheriting, use Class.new( superclass )
dummy2 = eval("#{dynamic_name}")
puts "dummy2: #{dummy2}"

どのように解決するのですか?

クラスの名前は、それを参照する最初の定数の名前に過ぎません。

すなわち、もし私が myclass = Class.new として、次に MyClass = myclass とすると、クラス名は MyClass . しかし、私は MyClass = を実行するまでクラスの名前が分からないのであれば、それはできません。

ですから、代わりに Module#const_set を使うことで、動的にconstの値を設定することができます。例

dynamic_name = "ClassName"
Object.const_set(dynamic_name, Class.new { def method1() 42 end })
ClassName.new.method1 #=> 42