在继承进程时获取匿名类的名称

时间:2014-04-19 22:18:46

标签: ruby class metaprogramming

是否有可能在继承中获取匿名类的name,而不是引发“失败的A”?应该通过Class对象创建(没有评估或类似)。

class A
  def self.inherited(base)
    raise 'fail A' unless base.name
  end
end

B = Class.new(A)
# or
Object.const_set :B, Class.new(A)

上面的代码不起作用,因为匿名类尚未初始化,因此无法将其设置为特定的常量。

2 个答案:

答案 0 :(得分:5)

没有

匿名类在被分配给常量(例如(B = Class.new).name #=> "B")之前没有名称。由于在创建类实例之后(在此期间调用了包含inherited的钩子)之后才进行赋值,所以在此之后你无法获得该名称。

答案 1 :(得分:1)

如下:

class Superclass
  def self.inherited(base)
    raise 'Invalid class name' unless @forced_anonymous_subclass_name == :A
  end
  def self.forced_anonymous_subclass_name
    @forced_anonymous_subclass_name
  end
  def self.with_forced_anonymous_subclass_name(class_name)
    @forced_anonymous_subclass_name = class_name
    yield
  ensure
    @forced_anonymous_subclass_name = nil
  end
end

sc = Superclass

sc.with_forced_anonymous_subclass_name(:A) do
  Object.const_set sc.forced_anonymous_subclass_name, Class.new(sc)
end #=> A

sc.with_forced_anonymous_subclass_name(:B) do
  Object.const_set sc.forced_anonymous_subclass_name, Class.new(sc)
end #=> RuntimeError

随意询问是否有明确/改进/等等。