确定方法在飞行中的可见性

我正在编写一个方法来定义类中的实例方法; 与attr_accessor类似的东西:

class Foo custom_method(:foo) end 

我已经通过向Module模块添加custom_method函数并使用define_method定义方法来实现它,它工作正常。 但我无法弄清楚如何从课程中考虑可见性属性。 例如,在以下类中

 class Foo custom_method(:foo) private custom_method(:bar) end 

第一个生成的方法(foo)必须是公共的,第二个(bar)必须是私有的。 我怎么做? 或者,如何找到调用custom_method的上下文:private,public或protected?

谢谢!

经过一番试验后,我感到非常困惑。 最初,我认为当您调用Module#define_method时,Ruby会将默认可见性(公共,私有或受保护)考虑在内。 事实certificate,在Ruby版本<= 2.0上,情况并非如此:

 class Foo private define_method :foo do puts "Foo called!" end end Foo.new.foo # Prints "Foo called!" 

在Ruby 2.1+上,它更令人困惑。 Module#define_method似乎考虑了默认方法可见性:

 class Foo private define_method :foo do puts "Foo called!" end end Foo.new.foo # NoMethodError: private method `foo' called for # 

但它只适用于直接在类中调用define_method的情况。 调用然后调用define_method的方法不起作用:

 class Foo def self.hello_on name define_method name do puts "Hello, #{name}!" end end private hello_on :foo end Foo.new.foo # Prints "Hello, foo!" 

钻它Ruby! 为什么?

好的,这需要绝望的措施……

 module DefaultMethodVisibilityAccessor attr_reader :current_default_method_visibility def public(*args) @current_default_method_visibility = :public if args.empty? super end def protected(*args) @current_default_method_visibility = :protected if args.empty? super end def private(*args) @current_default_method_visibility = :private if args.empty? super end end class Module prepend DefaultMethodVisibilityAccessor end module MethodDefiner def hello_on name define_method name do puts "Hello, #{name}!" end case current_default_method_visibility when :public public name when :protected protected name when :private private name end end end 

用法:

 class Foo extend MethodDefiner hello_on :foo private hello_on :bar end Foo.new.foo # Prints "Hello, foo!" Foo.new.bar # NoMethodError: private method `bar' called for # 

那里,修好了!

我认为这是不可能的,因为Module.private设置的范围可见性级别是在C虚拟机级别管理的,而不是暴露给Ruby。

编辑:它只能在调用它的同一语法范围内使用,所以当你调用custom_method它会失去在类声明中设置的可见性级别。

它在set_visibility()中设置,并在vm_define_method()中使用 ,但我找不到对Ruby提供的相应变量的任何引用。

我建议使用某种自定义参数来指定方法的可见性级别。

你可以使用Module#private_method_defined吗? validation方法是否定义为私有