1

假设我有一个 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

我怎样才能做到这一点?提前致谢。

4

2 回答 2

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此代码可能不正确。

于 2012-12-14T18:21:26.703 回答
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 等会发生什么。

于 2012-12-14T18:39:57.723 回答