如何声明一个私有方法
class Wolf
def scare
"scaring..."
end
private
def sleep
"sleeping.."
end
def eat
"eating.."
end
end
所有高于关键字 "private "的方法被认为是公共的,所有低于关键字的方法被认为是私有的。
注意,这里的 "private "不是一个关键词,而是内核模块的一个方法。
什么是Ruby中的私有方法
一个私有方法不能从外部调用。让我们在IRB控制台中使用一只狼。要使用我们上面的狼,只需在控制台中复制/粘贴这个类(控制台将亲切地接受回车键)
$irb(main)> w = Wolf.new
=> #<Wolf:0x00007fee2c760440>
$irb(main)> w.scare
=> "scaring..."
$irb(main)> w.sleep
Traceback (most recent call last):
1: from (irb):38:in `<main>'
NoMethodError (private method `sleep' called for #<Wolf:0x00007fee2c760440>)
现在你明白了。一个对象可以决定隐藏其内部行为,以确保一致性。
Ruby中的私有方法:恼人的部分
为什么要攻击一个著名的OOP原则?因为我觉得这个隐私很烦人。有一些角落的情况。
- 你希望只有一个其他的类可以访问这个私有方法(但没有其他的类)。
- 你想测试一个私有方法,因为常规方法(通过可用的公共方法测试一个私有方法)不起作用。
- 你必须考虑层次结构,以及如何处理 "受保护 "的方法,以及这种层次结构是否适合你的需要。
Ruby很好地避免了这种精神上的头痛:你可以使用.send方法来绕过隐私规则。
$irb(main)> w.send('sleep')
=> "sleeping.."
但是为什么要浪费这么多精力呢...一次是定义什么是隐私或不隐私,另一次是确定我们可以绕过限制。
我们还需要这种隐私吗?
也许是的。我在想开放源代码项目。维护者不希望最终的用户操作私人的东西,并破坏Ruby gem的内部行为(并在Github上提出一些问题...)。OOP的存在是有原因的。
但对于你的商业、日常应用,我认为这是一个负担。 通常情况下,这些应用程序已经是私有的了。想想Rails应用程序:没有人可以看到你的代码。/public文件夹是为前端资产准备的,而不是你的代码库。
因此,我通过使用下划线作为后缀来绕过 "私有 "这个关键词。我们的狼现在看起来就像这样。
class Wolf
def scare
"scaring..."
end
def _sleep
"sleeping.."
end
def _eat
"eating.."
end
end
每次我遇到下划线,我就知道它意味着 "嘿,要注意这是一个脆弱的东西,理论上只有这个类,或其他类,或测试,可以使用它"。
当然,它不是在这里发明的。在我的印象中,像VueJS这样的框架使用双底线作为后缀,我也在其他项目中看到过这种惯例。
Ruby递归函数中的私有方法
这种隐私还有一个用例:私有参数。
假设我有一个递归函数,我必须跟踪该函数被调用的次数以避免无限循环。
def countdown(n, _number_of_calls = 0)
if n < 1
return
elsif _number_of_calls > 5
puts 'too much calls, exiting'
return
else
puts n
end
countdown(n-1, _number_of_calls + 1)
end
注意_number_of_calls不是公共参数的一部分。
$irb(main)> countdown(2)
2
1
=> nil
如果我超过了调用次数,我就退出递归。
$irb(main)> countdown(10)
10
9
8
7
6
5
too much calls, exiting
=> nil
结论
私有方法是必要的,这是OOP语言中的一个基本要素。然而,对于你的商业应用来说,有一个很好的缩短方式:下划线--或者你喜欢的任何其他约定。