在Ruby中声明“私有”/“受保护”时实际发生了什么?
在Ruby类定义中声明private
/ protected
时实际发生了什么? 它们不是关键字 ,因此这意味着它们必须是方法调用,但我无法找到它们的定义位置。 它们似乎没有记录。 声明private
/ protected
方法(如下所示)的两种不同方式是否以不同方式实现? (第二种方式显然是一种方法调用,但这在第一种方式中并不那么明显。)
class Foo private def i_am_private; end def so_am_i; end end class Foo def i_am_private; end def so_am_i; end private :i_am_private, :so_am_i end
两者都是方法调用。 引用文档 :
每个function可以以两种不同的方式使用。
- 如果不带参数使用,则这三个函数设置后续定义方法的默认访问控制。
- 使用参数,函数设置命名方法和常量的访问控制。
请参阅此处的文档
- Module.private
- 访问控制
您正在寻找Module.private
方法如何存在。 这就是发生的地方 。 这里有一些关于它的更多信息 。 您必须从rb_define_private_method
定义的class.c
开始,阅读更多class.c
。
希望有所帮助!
我想补充一些类似关键字的行为,因为答案更多的是关于何处而不是如何 ; 答案在于Ruby的复杂元编程function。 可以使用它们作为使用method_added
钩子的关键字 ; Ruby中的一个钩子是一个在特定事件(即钩子的名称)出现时调用的函数。 重要的是method_added
钩子接收已经定义的方法的名称作为他的参数:这样,就可以修改它的行为。
例如,您可以使用此钩子来定义类似于Python的装饰器的行为; 重要的是,与private
和protected
方法不同,这个类似装饰器的方法应该定义一个method_added
定义的method_added
:
class Module def simple_decorator eigenclass = class << self; self; end eigenclass.class_eval do define_method :method_added do |name| eigenclass.class_eval { remove_method :method_added } old_name = 'old_' + name.to_s alias_method old_name, name class_eval %Q{ def #{name}(*args, &block) p 'Do something before call...' #{old_name}(*args, &block) p '... and something after call.' end } end end end end class UsefulClass simple_decorator def print_something p "I'm a decorated method :)" end def print_something_else p "I'm not decorated :(" end end a = UsefulClass.new a.print_something a.print_something_else
simple_decorator
看起来像一个语言关键字,行为像private
; 但是,因为它删除了method_added
钩子,所以它仅适用于紧随其后的方法定义。