"public"、"private"和"protected"方法究竟有什么作用?



几乎所有关于 Ruby 中 OOP 的体面资源都指出存在访问修饰符 - 关键字publicprivateprotected- 并展示了如何正确使用它们。很少有人解释这些修饰符不是关键字,而是实际方法,并且调用它们会修改将来在此特定类中定义的所有方法的可见性。但是,我找不到有关他们实际上如何做到这一点的任何信息。它们是否更改了特殊的内部变量,或者是否更改了当前作用域/绑定的属性,或者它们是否设置了一些特定的解释器标志,或者......还是什么?

我自己做了一些研究,但它让我比以前更加困惑。请考虑以下代码片段:

class Test
public
define_method :public_define_method do 
puts 'Public define_method'
end
private
define_method :private_define_method do 
puts 'Private define_method'
end
public
def public_def
puts 'Public def'
end
private
def private_def
puts 'Private def'
end
end
t = Test.new
t.public_define_method
t.private_define_method
t.public_def
t.private_def
#Output:
#> Public define_method
#> Private define_method
#> Public def
#> sandbox.rb:29:in `<main>': private method `private_def' called for #<Test:0x00000001cdfd38> (NoMethodError)

我一直认为def是一种优化的语法糖,用于define_method具有创建新的变量可见性范围的额外怪癖,但显然,它似乎还有更多 - 用def创建的方法受private/public修饰符的影响,而用define_method创建的方法则不受。此外,define_method没有任何与更改方法可见性相关的参数,这使我得出结论,有关它的信息必须存储在类中,而不是方法本身 - 因此应该是访问修饰符设置的标志。但是为什么defdefine_method如此不同呢?后台会发生什么?它是否检查访问修饰符方法设置的标志,然后将自己添加到类私有/受保护方法的一些特殊隐藏寄存器中?..

简而言之,我很困惑,如果能澄清这个问题,我会很高兴。提前感谢!

确切地说?

公共http://apidock.com/ruby/Module/public

如果没有参数,则将后续定义的方法的默认可见性设置为 public。使用参数,将命名方法设置为具有公共可见性。

源:

static VALUE
rb_mod_public(int argc, VALUE *argv, VALUE module)
{
secure_visibility(module);
if (argc == 0) {
SCOPE_SET(NOEX_PUBLIC);
}
else {
set_method_visibility(module, argc, argv, NOEX_PUBLIC);
}
return module;
}

私人http://apidock.com/ruby/Module/private

如果没有参数,则设置后续的默认可见性 将方法定义为私有。使用参数,将命名方法设置为 具有私有可见性。

源:

static VALUE
rb_mod_private(int argc, VALUE *argv, VALUE module)
{
secure_visibility(module);
if (argc == 0) {
SCOPE_SET(NOEX_PRIVATE);
}
else {
set_method_visibility(module, argc, argv, NOEX_PRIVATE);
}
return module;
}

受保护http://apidock.com/ruby/Module/protected

如果没有参数,则设置后续的默认可见性 定义了要保护的方法。使用参数,设置命名方法 具有受保护的可见性。

static VALUE
rb_mod_protected(int argc, VALUE *argv, VALUE module)
{
secure_visibility(module);
if (argc == 0) {
SCOPE_SET(NOEX_PROTECTED);
}
else {
set_method_visibility(module, argc, argv, NOEX_PROTECTED);
}
return module;
}

但是,这对此信息的实际应用程序并没有真正的帮助。您可能会在诸如"私有"、"公共"和"受保护的方法"之间有什么区别?和 为什么 Ruby 同时有私有方法和保护方法?

最新更新