假设我有一个A类如下:
class A
class B
end
class C < B
end
...
end
我想创建一个与A
具有相同嵌套类结构的类D.class D
Replicate nested class structure of A here
end
我希望D看起来像:
class D
class B
end
class C < B
end
...
end
这样我可以用不同的结果做A :: B和D :: B
我怎样才能做到这一点?提前谢谢。
答案 0 :(得分:2)
class Module
def replicate m
m.constants.each do |sym|
case mm = m.const_get(sym)
when Class then const_set(sym, Class.new(mm.superclass)).replicate(mm)
when Module then const_set(sym, Module.new(mm.superclass)).replicate(mm)
end
end
end
end
class D
replicate A
end
但superclass
部分可能与此代码不正确。
答案 1 :(得分:1)
class A
end
class D
end
[A, D].each do |c|
c.class_eval %Q(
class B
def bar; puts "B#bar in #{c} is not shared" end # <--- new
end
class C < B
def foo; puts "C#foo in #{c}" end
end
)
end
p A.constants
p A::C.instance_methods(false)
p D.constants
p D::C.instance_methods(false)
A::C.new.foo
D::C.new.foo
新
A::B.new.bar
D::B.new.bar
=begin
class B # creates a new class B
def quux; puts "A::B#quux in #{self}" end
end
A::B.new.quux #=> undefined method `quux' for #<A::B:0x101358a98> (NoMethodError)
=end
class A::B # reopens B in A
def quux; puts "A::B#quux in #{self}" end
end
A::B.new.quux
执行:
$ ruby -w t.rb
["B", "C"]
["foo"]
["B", "C"]
["foo"]
C#foo in A
C#foo in D
新
B#bar in A is not shared
B#bar in D is not shared
A::B#quux in #<A::B:0x10402da28>
它比复制整个内部结构更复杂,包括方法和可能的变量。为此,你需要反思,或者可能需要进行反思。
新增:如果你在%Q()里面放了一些东西,class_eval会为每个类评估它,因此它不会被共享。 B不是独立的,你有两个不同的类A :: B和D :: B.
如果要为两个类添加相同的代码,请创建一个模块并包含它。 Ruby创建一个指向模块的代理,并将代理插入从对象类到其超类的指针链中,这样搜索方法机制将在类的方法之后和之前的方法之前查找模块的方法。超类。
class D
extend A
end
将A的实例方法定义为D的类(单例)方法。听起来很难看。我认为你应该试验,展示puts,p,instance_methods,singleton_methods等会发生什么。