Ruby中用#标识方法的惯例是什么?这个惯例的缘由/历史是什么?

9
例如,我一直看到方法被称为String#split,而不是String.split,后者似乎更合乎逻辑。或者甚至可以使用String::split,因为您可以将#split视为String的命名空间中的方法。我甚至看到过仅出现方法时,假定/暗示了类(#split)。
我了解这是在ri中标识方法的方式。哪个先出现的?
这是为了区分例如方法和字段吗? 我还听说这有助于区分实例方法和类方法。但这是从哪里开始的?

我想知道为什么在讨论Ruby命名约定时,书籍/教程中没有提到或解释这个约定。在各种讨论中看到带有“#”前缀的方法名称,只能猜测前缀的重要性,这让我感到困惑。事实上,“#”在.rb源文件中表示注释,这使得情况变得更加混乱。正如你所想象的那样,这不是最容易搜索的事情,所以感谢你在某个地方提出了这个问题,让我能够偶然发现它。我想知道当我在6个月的非Ruby活动后忘记这些细节时,是否还能再次找到它... - Michael Burr
2个回答

8
区别在于你访问方法的方式不同。 类方法使用::分隔符来表示消息可以发送到类/模块对象,而实例方法使用#分隔符来表示消息可以发送到实例对象。
我将选择Complex类(在Ruby 1.9中)来演示区别。你有Complex::rectComplex#rect两种方法。这些方法具有不同的元数和完全不同的用途。Complex::rect接受一个实部和一个虚部参数,返回一个新的Complex实例,而Complex#rect返回实例的实部和虚部组成的数组。
ruby-1.9.1-p378 > x = Complex.rect(1,5)
 => (1+5i) 
ruby-1.9.1-p378 > x.rect
 => [1, 5] 
ruby-1.9.1-p378 > x.rect(2, 4) # what would this even do?
ArgumentError: wrong number of arguments(2 for 0)
    from (irb):4:in `rect'
    from (irb):4
    from /Users/mr/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>'

我认为他们不把“.”作为一切的分隔符的原因是,这会让人产生歧义,无法确定方法是属于类还是实例。现在我已经习惯了Ruby这样做,实际上我认为其他语言的约定有点不足取,老实说。

此外,这与“字段”有些完全无关,因为所有可以发送的消息都是消息,即使它看起来像一个公开可访问的字段。当然,最接近字段的东西是属性或实例变量,它们总是以“@”为前缀,并且除非您使用继承或“Object#instance_variable_get / _set”,否则从实例外部不直接可访问。

至于为什么他们选择了“::”和“#”? “::”对我来说很有意义,因为它通常分隔命名空间,但是“#”可能只是一个在其他命名中没有使用过的符号,并且可以被明确地识别为实例方法分隔符。


现在说到加分问题:为什么不使用::调用类方法,而使用来调用实例方法?这样,在阅读文档和实际代码时就没有歧义了。 - JUST MY correct OPINION
@JUST:你可以使用Complex::rect(1,5)。但是由于#开头的行注释,我认为后者不会很快被采用。 - Mark Rushakoff
1
我知道这个。问题是使用#而不是.进行文档记录仍然相当奇怪。特别是因为你可以使用::调用。这对我来说是Ruby中难以言喻的奥秘之一。既然我们已经有了@@@前缀规则,为什么不对方法做同样的事情,并强制(不允许,强制)使用::调用类方法并强制(不允许,强制)使用.调用实例方法? - JUST MY correct OPINION
@JUST:那是一个合理的问题。我没有关于这个问题的权威答案,但我猜主要原因是它会破坏所有向后兼容性。此外,它在某种程度上会吓跑新手,但这只是次要问题。 - Mark Rushakoff
4
在Ruby中没有不同种类的方法调用约定的原因很简单,那就是因为在Ruby中根本就没有不同种类的方法。只有实例方法存在。 - Jörg W Mittag
什么...Math::sqrt(9) 让我大吃一惊。 - Justin L.

3
我了解这是在ri中标识方法的方式。那么哪个先出现呢?
是的,它来自这里。当你使用“#”时,它会自动超链接你的方法,因此文档中对其他方法的引用开始以“#”符号为前缀。请参见此处
“类名、源文件名和任何包含下划线或以井号字符开头的方法名都将从注释文本自动超链接到它们的描述。”
但是你不能通过这种方式调用一个方法。不过这并不奇怪;毕竟,“<cref ...>”虽然是一个有效的文档标记,但在C#中却是无效的语句。

这是方法首次被哈希引用的地方吗? - Justin L.
@Justin L.:是的,它创造了这个惯例。 - John Feminella
这是因为rdoc文件使用方法名称作为锚点ID,而HTML使用#将位置哈希与文档标识符分隔开吗? - Tim Snowhite

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接