如this answer中所述,在Ruby 2.1或更高版本中,此代码:
class SimpleTest
private
define_method :foo do
42
end
end
将foo
定义为SimpleTest
个实例的私有方法。 (在Ruby 2.0和更早版本中它不会是私有的。)但是,我希望做一些不那么微不足道的事情。我想定义类可以扩展的DSL,并希望DSL内部定义的方法尊重调用上下文的私有/受保护可见性。这可能不太清楚,所以这是一个例子:
module Dsl
def has_a(name)
define_method name do
42
end
end
end
class Test
extend Dsl
private
has_a :thing
end
如上所述,该代码将在thing
个实例上定义 public Test
方法。相反,我希望has_a
能够反映调用它的方法可见性(在本例中为private
),并在同一方法可见性下定义thing
。
我不熟悉Ruby的C源代码,但是我快速查看了this function,看起来它可能做我想要的,但我不认为它可以从Ruby访问。 (似乎只使用了here。)我还查找了define_method
的文档(因为第一个示例按照需要运行)here,它看起来像noex
变量声明并在此处设置:
int noex = NOEX_PUBLIC;
const NODE *cref = rb_vm_cref_in_context(mod, mod);
if (cref) {
noex = (int)cref->nd_visi;
}
可能是我想要的价值,但我又不知道如何在Ruby中获得它,或者即使它能够反映出调用范围(在Test
中)。假设我具有可见性,那么我可以在private name
内protected name
之后调用define_method
(或has_a
),如果它未在public
中调用} context。
思考?有没有办法做到这一点,还是我运气不好?