Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在继承进程时获取匿名类的名称_Ruby_Class_Metaprogramming - Fatal编程技术网

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

Ruby 在继承进程时获取匿名类的名称,ruby,class,metaprogramming,Ruby,Class,Metaprogramming,是否有可能在继承中获取匿名类的名称,而不引发失败?应该通过类对象创建而不是eval或类似 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) 上面的代码不起作用,因为匿名类尚未初始化,因此无法将其设置为特定常量。否 匿名类只有在被分配给常量(例如B=class.new.na

是否有可能在继承中获取匿名类的名称,而不引发失败?应该通过类对象创建而不是eval或类似

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)
上面的代码不起作用,因为匿名类尚未初始化,因此无法将其设置为特定常量。

匿名类只有在被分配给常量(例如B=class.new.name=>B)后才有名称。由于在创建类实例并调用钩子(包括继承的钩子)之前,分配不会发生,因此在创建类实例之后才能获得名称。


匿名类只有在被分配给常量(例如B=class.new.name=>B)后才有名称。由于在创建类实例并调用钩子(包括继承的钩子)之前,分配不会发生,因此在创建类实例之后才能获得名称。

类似于:

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

请随时询问是否存在不清楚/改进/等问题。

以下内容如何:

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

请随时询问是否存在不清楚/改进/等。

是的,没错,但可能存在一些漏洞。我试图定义def self.name;'B';在块中结束,因为我认为它将首先定义name类方法,然后调用inherited,但不是。对我来说,这种行为真的很奇怪。这不起作用,因为如上所述,在计算具有方法定义的块之前调用了钩子,所以该方法还不存在。是的,没错,但可能有一些黑客。我试图定义def self.name;'B';在块中结束,因为我认为它将首先定义name类方法,然后调用inherited,但不是。对我来说,这种行为真的很奇怪。这不起作用,因为如上所述,在对具有方法定义的块求值之前调用了钩子,所以该方法还不存在。Hello@mdesantis,我真正想解决的是这个问题:您的解决方案将无法工作,因为它会在ActiveSupport代码中的某个地方检查name方法。但我会检查,以确保它不会工作。。。也许你知道一些更干净的解决方案?哦。。。那条线有什么问题?你说的是什么问题?如果你告诉我你试图解决的问题,我们可以推理;你需要替换eval?没错,我不知道如何用更合适的东西来替换eval,比如Module.new。那么Object.const\u set config.controller\u name,Class.newActiveAdmin::PageController呢?考虑过了吗?我不明白你所说的评估是什么意思。在这种情况下,eval似乎是适当的定义。也许你的意思是更优雅,但你在这里谈论的是一个边缘案例:基本上你想要一个名为匿名类init op的原子。这不是一个通常需要的东西,我认为它是eval的完美用例。如果这让你很困扰的话,那么我认为最容易解决的问题是使可继承类与匿名类兼容,这可能比一个新的核心功能更合理,因为它需要数年时间才能成为足够依赖的标准。Hello@mdesantis,我真正想解决的是这个问题:你的解决方案将不起作用,因为它会在ActiveSupport代码的某个地方检查name方法。但我会检查,以确保它不会工作。。。也许你知道一些更干净的解决方案?哦。。。那条线有什么问题?你说的是什么问题?如果你告诉我你试图解决的问题,我们可以推理;你需要替换eval?没错,我不知道如何用更合适的东西来替换eval,比如Module.new。那么Object.const\u set config.controller\u name,Class.newActiveAdmin::PageController呢?考虑过了吗?我不明白你所说的评估是什么意思。在这种情况下,eval似乎是适当的定义。也许你的意思是更优雅,但你在这里谈论的是一个边缘案例:基本上你想要一个名为匿名类init op的原子。这不是一个通常需要的东西,我认为它是eval的完美用例。如果这让你很困扰的话,那么我认为最简单的方法就是让可继承类与匿名类兼容,这可能比一个新的核心特性更合理,因为它需要几年的时间才能成为足够依赖的标准。