2013-03-07 42 views
0

当我们试图重新定义一个常量时,Ruby只显示一个警告,但没有任何错误。所以人们总是可以在Ruby中重新定义一个常量?允许重新定义Ruby常量并允许通过send()方法访问私有方法的基本原理?

Const = 12 
puts Const 
#only an warning: already initialized constant Const 
Const = 14 
puts Const #Displays 14 
class MyClass 
private 
    def priv 
     puts 'In private method' 
    end 
end 
obj = MyClass.new 
#Error: private method `priv' called for #<MyClass:0x7f2cfda21738> (NoMethodError) 
#obj.priv 
#but this is fine! 
obj.send(:priv) 

是否有红宝石这样的设计之后的任何理由:

也是一类的私有方法可以使用send方法被调用?这些不是违反常量和访问说明符的基本概念吗?

这些设计是否有任何实际用途?如果有的话,一些例子会很棒!

注意:在这里我看到很多关于Ruby常量和私有方法的问题/讨论,但是我没有发现任何与这些背后原因相关的问题。

+0

我觉得很简单。 Ruby不是Java。访问说明符是指南,而不是规则。 – Linuxios 2013-03-07 14:28:35

+0

@Linuxios忘记Java或任何其他语言,只考虑英文单词*'constant'*和*'private'*。这些Ruby的设计不要违反这两个词的解释吗?我已经读过,Ruby试图尽可能接近英语口语!事实上,流行的Ruby书籍[为什么(对于ruby而言)(指向ruby)](http://mislav.uniqpath.com/poignant-guide/book/)实际上意味着Ruby接近于自己如何思考或阅读自己的想法介意...... – Curious 2013-03-07 14:37:09

+1

Ruby不会试图成为一种执行规则的迂腐语言,例如常量被永久锁定。如果是这样,我们应该能够使用的唯一常数就是我们在科学计算器中发现的那些常数。相反,常量是我们不想改变的东西,但是如果我们意外地做了,Ruby会警告我们,以便我们修复导致警告的代码。作为一名程序员,Ruby对我提出异常并停止代码或者在没有这样说的情况下默默地忽略重新分配没有好处,所以它的当前行为很好地工作。 – 2013-03-07 15:12:00

回答

3

至于send,答案很简单:一旦你使用反射,所有的投注都关闭。请注意,这与其他大多数语言也没什么不同,例如,您也可以使用反射规避Java中的访问限制。

而对于常量,那么你得到一个警告。你被告知你正在做一些你不应该做的事情。但是Ruby是一种相信你的语言,你知道你在做什么。它不会妨碍你。如果你想在脚下自己射击,你应该被允许这样做。或者,更加愤世嫉俗的方式来看待它:在Ruby中可以做很多邪恶的事情,重新定义常量确实无关紧要。