What's the rationale/history for the # convention of identifying methods in Ruby?

别等时光非礼了梦想. 提交于 2019-12-04 02:58:02

The difference indicates how you access the methods.

Class methods use the :: separator to indicate that message can be sent to the class/module object, while instance methods use the # separator to indicate that the message can be sent to an instance object.

I'm going to pick the Complex class (in Ruby 1.9) to demonstrate the difference. You have both Complex::rect and Complex#rect. These methods have different arity and they serve entirely different purposes. Complex::rect takes a real and an imaginary argument, returning a new instance of Complex, while Complex#rect returns an array of the real and imaginary components of the instance.

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>'

I think the reason that they don't use . as the separator for everything is that it would be ambiguous whether the method belongs to a class or an instance. Now that I'm used to Ruby doing this, I actually see it as a drawback to other languages' conventions, to be honest.

Also, this is somewhat of a completely unrelated topic from fields because all messages you can send are messages, properly speaking, even if it looks like a publicly accessible field. The closest thing you have to fields are attributes or instance variables, of course, which are always prefixed with @ and are not directly accessible from outside the instance unless you are using inheritance or Object#instance_variable_get/_set.

As to specifically why they chose :: and #? :: makes sense to me because it conventionally separated namespaces, but # was probably just a symbol that wasn't used in other nomenclature and could unambiguously be recognized as an instance-method separator.

I understand that this is the way methods are identified in ri. Which came first?

Yes, this is where it came from. When you use #, it automatically hyperlinks your methods, so references to other methods in documentation began being prefixed by the # sign. See here:

Names of classes, source files, and any method names containing an underscore or preceded by a hash character are automatically hyperlinked from comment text to their description.

You can't actually invoke a method this way, however. But that shouldn't be surprising; after all, <cref ...> is an invalid statement in C# despite being a valid documentation tag.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!