在Ruby类定义中声明private
/ protected
时实际发生了什么?它们不是keywords,因此这意味着它们必须是方法调用,但我无法找到它们的定义位置。它们似乎没有记录。声明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
答案 0 :(得分:9)
两者都是方法调用。引自docs:
每个功能可以两种不同的方式使用。
- 如果不带参数使用,则这三个函数设置后续定义方法的默认访问控制。
- 使用参数,函数设置命名方法和常量的访问控制。
醇>
请参阅此处的文档:
您正在寻找Module.private
方法的存在方式。 Here is where that happens。关于它,here is some more information。从rb_define_private_method
中定义的class.c
开始,您需要阅读更多内容。
希望有所帮助!
答案 1 :(得分:0)
我想添加一些关于类关键字行为的内容,因为答案更多地是关于 where 而不是如何;答案在于Ruby的复杂元编程功能。
可以使用{em>关键字来使用method_added
钩子; Ruby中的钩子是在发生特定事件(即钩子的名称)时调用的函数。
重要的是method_added
挂钩作为参数接收已定义方法的名称:这样,就可以修改它的行为。
例如,您可以使用此钩子来定义类似于Python的装饰器的行为;重要的是,与private
和protected
方法不同,这种类似装饰器的方法应该定义一个取消定义自己的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
挂钩,它只适用于紧接着的方法定义。