如何在const_missing(),threadsafe中使用对象的实例变量?

时间:2014-04-11 20:43:50

标签: ruby metaprogramming

我想将某些大写标识符视为动态计算的常量 - 所以当我评估代码字符串如eval(" foo(BAR)")时,我可以查找BAR的值并提供它评估。

不要问我为什么要这样做。 : - )

问题是const_missing()(不像是method_missing())必须是类方法,而不是实例方法。所以,如果我尝试编写这样的函数:

  def self.const_missing(name)
    if @data[name]
      return @data[name]
    end
    raise "Missing const #{name.inspect}"
  end

我无法看到实例变量@data告诉我FOO的价值应该是什么。

我当然可以使用类变量@@ data,但这不会让我为每个对象提供不同的数据。我可以在执行eval之前立即从@data设置@@ data,但这不是线程安全的,也不是递归友好的。

我的后备是使用线程本地存储来包含一堆@data,并在eval调用之前和之后推送和弹出@data。但感觉如此......不优雅。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

  

甚至不问我为什么要这样做。 : - )

对于这个建议,请问你为什么这么做呢?

我在问,因为如果你试图解释你想要解决的问题,人们可能会向你展示一种不同的方法。

另外,不要使用eval。只是不要!如果您无法使用其他可能的元编程方法,例如class_eval instance_eval method_missing和朋友,那么您可能做错了。

让我强调,不要使用eval()