When I see any Ruby method printed in text, it usually appears as:
Class#method
or
#method
Now, I would use:
Class.method
Why are all Ruby methods preceded by a pound sign? Is there any reason for it?
Note that the convention is:
Class#method
rather than
object#method
In code you would have object.method, if object was an instance of class. The # convention is not used in code.
From the RDoc documentation:
Use :: for describing class methods, # for describing instance methods, and use . for example code.
The # notation is used to refer to the canonical instance method, like String#upcase. The . notation is used to refer to the method of a particular instance, like mystring.upcase. The distinction is made to not imply that a class method 'upcase' exists.
I just realized that none of the other answers touch the most trivial aspect of the question: why the # sign?
I have two theories:
It might come from Smalltalk, where symbols are written #sym (instead of :sym) as they are in Ruby. So, if you want to refer to a Method object (as opposed to calling a method), then you would call something like Array >> #new. (The >> is itself a method that returns the method passed to it. So, in Ruby that would be Array.method :new.) In Smalltalk documentation, methods are generally referred to as Class>>method, but in Ruby Class:method would have made more sense, except that it is easily confused with Class::method. Therefore, Class#method was chosen.
My other theory is that it simply was chosen because # is the comment character in Ruby.
A definitive answer can only be given by whoever invented that convention. If it was invented for the Programming Ruby book, that would be either Dave Thomas or Andy Hunt, but I kind of doubt that. The book came out in 2001, Ruby started in 1993, how were they referring to methods before then?
From the rdoc docs (emphasis mine):
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.
The hash notation was introduced "Programming Ruby - The Pragmatic Programmer's Guide" first published in December 2000.
The "Preface" contains "Notational Conventions":
Within the text, Fred#doIt is a reference to an instance method (doIt) of class Fred, while Fred.new [In some other Ruby documentation, you may see class methods written as Fred::new. This is perfectly valid Ruby syntax; we just happen to feel that Fred.new is less distracting to read.] is a class method, and Fred::EOF is a class constant.
This is clarified in the 2nd edition, published in October 2004:
Within the text, Fred#do_something is a reference to an instance method (in this case do_something) of class Fred, Fred.new is a class method, and Fred::EOF is a class constant. The decision to use a hash character to indicate instance methods was a tough one: it isn’t valid Ruby syntax, but we thought that it was important to differentiate between the instance and class methods of a particular class. When you see us write File.read, you know we’re talking about the class method read. When instead we write File#read, we’re referring to the instance method read.
Ruby itself uses this notation:
> rvm use 1.9.3
Using ruby-1.9.3-p551
> Object.instance_method(:initialize)
=> #<UnboundMethod: Object(BasicObject)#initialize>
It was introduced and formalised by Matz in February 2002:
commit 8210c254bee19294af67bcee0e8f5e02ebb39a60
Author: matz <matz#b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Tue Feb 5 07:56:31 2002 +0000
* io.c (fptr_finalize): should raise error when fclose fails.
* eval.c (method_inspect): proper output format to distinguish
methods and singleton methods.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk#2046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
All the answers above you list are correct. The one thing I would add is that the documentation style you said you would perfer
Class.method
would be easily confused with class methods. Since you can call class methods in ruby using the above syntax:
class Foo
def self.say_hi
puts "hi"
end
end
Foo.say_hi # => prints "hi"
This was mentioned in the JS version of this question, but it seems likely this nomenclature came from JavaDoc where the hash mark is translated directly into an on-page reference, e.g. href="Component.html#getComponentAt(int, int)"
heff's answer (which I can't comment on due to lack of reputation), that Ruby followed JavaDoc's example, is the best guess in my view. The JavaDoc designers needed or wanted a way to distinguish package qualifiers (which they used the dot for) from class qualifiers (which they used the hash for). JavaDoc's #see and #link tags syntax looks like this:
#see package.class#member [optional label]
{#link package.class#member [optional label]}
See the documentation of JavaDoc's package.class variant of the #see tag and the documentation of JavaDoc's #link tag, which heff already pointed to.
In JavaDoc, the package name can often be omitted, so that only the Class#member part remains, which looks equally strange as in Ruby, because Java code uses the Class.member syntax,
just as Ruby does.
It would be interesting to find out why the JavaDoc designers needed the differing syntax, while the Java compiler does fine with dots for both purposes.
Related
Both . and :: can be used to call class methods, but, in my experience, . is by far the most commonly used of the two. So I am accustomed to using that form in documentation and RSpec describe/context/expect strings.
However, the Ruby API documentation uses :: (e.g. at https://rubyapi.org/3.1/o/string). Is that intended to mean that that form is preferred for the cases I described?
Note: This is not a duplicate of Is there a difference between :: and . when calling class methods in Ruby?. That question refers to the use of the two alternate notations in Ruby source code, whereas this question refers to documentation and other textual descriptions (e.g. in rspec strings). There may be reasons to make different choices in code vs. documentation, for example, that using . in code more clearly indicates a message call vs. a constant access, whereas in documentation :: might be preferred to more dramatically distinguish class methods from instance methods.
As far as I know RuboCop always suggets to use . when calling class method, as explained here.
Looking at documentation you have linked regarding the class String, they seem to use a single . when calling class methods, as seen here.
Actually I was not able to find a code snippet in that doc page that uses the :: notation for calling a class method.
If you are referring to the menu on the left, which uses :: to indicate class methods and # for instance methods, it's a Ruby documentation convention and has no real meaning in actual code.
Maybe this could be an helpful resource.
The following code is valid:
(1..5).to_a
(1..5) is a Range. The method to_a appears to convert a range to an array.
However, the documentation for Range does not document. Since this documentation is presumably auto-generated from the source with Yard, I doubt it could not be in the list of methods. Is there auto conversion going on?
How is the above legal Ruby?
The following code is valid ruby:
b = (1..5).to_a
(1..5) is a Range object, and b is an Array object. The official(?) documentation for the Class Range does not document the method to_a, which appears to convert a range to an array.
So, how is the above legal Ruby?
Ruby has something called "inheritance". Inheritance is a method for differential code-reuse that actually does not only exist in Ruby, but is in fact quite popular in many languages such as Java, C♯, C++, Python, PHP, Scala, Kotlin, Ceylon, and so on and so forth.
Inheritance allows you to define methods in one place, and then inherit them in another place, overriding and defining only the methods whose behavior differs. Hence, "differential code re-use".
In this particular case, the method you are looking at is Enumerable#to_a.
Note: Ruby actually has two forms of inheritance, mixin inheritance and class inheritance. Mixin inheritance is like class inheritance where the mixin doesn't know its superclass. (The definitive resource about mixin inheritance is Gilad Bracha's PhD Thesis The Programming Language Jigsaw – Mixins, Modularity, and Multiple Inheritance.)
The official(?) documentation
Actually, ruby-doc is a third-party site. There is no official documentation site. (However, the documentation on ruby-doc is generated from documentation comments in YARV, one of the major Ruby implementations, and one that Yukihiro Matsumoto actively contributes to.)
Since this documentation is presumably autogenerated from the source with Yard,
It is actually autogenerated from the YARV source with RDoc, not YARD.
I'm confused how it could not be in the list of methods,
Note that the explanation I gave is the correct one, but there could be many other explanations. The most simple one: the reason why the method is not in the documentation is that it is not documented. Another reason could be a bug in the documentation generator that prevents the documentation for that method being displayed, a typo in the source code that prevents the documentation generator from recognizing the documentation, and many, many others.
so is there auto conversion going on?
No. Ruby does not have automatic conversions in the language. There are some methods which for reasons of efficiency are implemented in a non-object-oriented manner, and require an object to be an instance of a specific class (as opposed to the object-oriented manner, which would only require the object to conform to a specific protocol). Because it is a severe restriction to require an object to be an instance of a specific class, those methods will usually offer an "escape hatch" to the programmer, by sending a specific message and allowing the object to respond with an object of the required class.
For example, all methods printing something to the console, require an instance of String, but they will try sending to_s first, before rejecting the argument.
These are sometimes called "implicit conversions", but they have nothing to do with implicit conversions as in Scala or implicit casts as in C♯. They are in fact not even part of the language, they are just a convention for library writers.
My aim is to take an existing function, foo, and create an exact copy of it called bar, which is simple enough with alias_method. I would then like to dynamically redefine foo such that it has the exact same type signature, so that I can call bar from it, among other reasons.
This requirements mean that I cannot just do something like
define_method(:foo) do |*args, &block|
send(:bar, *args, &block)
end
because it changes the type signature of foo.
I also don't see how I can use something like method(:foo).parameters as that will tell me what the type signature is, but will not specify, for example, the values of default arguments.
Any help is greatly appreaciated!
Ruby has no concept of manifest types and manifest type signatures. Since they don't exist, you obviously can't get them.
When doing Ruby programming, there is of course a latent concept of types and type signatures in the programmer's head. But that's exactly where that concept exists: in the programmer's head and only in the programmer's head.
It might also exist in documentation, but that is not guarateed. Also, there is no standard format for putting it in documentation. There are various different formats for expressing types in Ruby documentation, sometimes the types are not expressed using any form of (semi-)formal notation at all, but only in prose, and sometimes, they are implicit in the names of parameters. In some cases, the types are just part of the Ruby culture, everybody knows them, but they are never actually written down anywhere (the most obvious example is the each protocol that the Enumerable mixin depends on, which everybody "just knows" without being explicitly specified).
You are also asking about default arguments for optional parameters: these are evaluated dynamically, getting static information about them is simply impossible because of the Halting Problem, Rice's Theorem and all the other fun undecidability results in programming.
TL;DR
Ruby doesn't care about types. It only cares about whether or not an object can #respond_to? a message. As a result, any hard-wired expectations about types should be encoded in method/variable names, and in the documentation.
Use Duck-Typing to Wrap Methods
The "Ruby way" is to use duck-typing rather than strict "type signatures." While there's nothing wrong with wrapping a method, your methods should:
Use meaningful argument names, if the type of an argument matters.
Perform implicit or explicit coercion or define singleton methods in the cases where you need an object to #respond_to? a method it doesn't currently support.
Implement singleton methods when necessary to permit duck-typing.
For example:
def foo array
array.is_a? Array
end
def flexible_foo string_or_array
if string_or_array.respond_to? :split
array = string_or_array.split /,?\s+/
else
array = string_or_array
end
foo array
end
flexible_foo 'a, b, c'
#=> true
flexible_foo %w[a b c]
#=> true
In this example, #foo expects an array. By wrapping #foo, we create a work-alike method that coerces the value into an array if it responds to the :split message, which String does and Array does not.
Documentation
Both RDoc and YARD do a reasonable job of documenting method signatures "out of the box," but YARD also has support for using tags to document things like "type signatures" and return types.
If your code is written with fixed expectations about what kinds of objects can be passed as arguments, then you can document those expectations in comments which RDoc or YARD will dutifully report. However, this is considered to be the programmer's responsibility rather than the Ruby interpreter's, and you'll know if you've broken the implicit contract when Ruby raises a NoMethodError exception at runtime.
This is one reason the Ruby community embraces test-driven development: since Ruby can redefine methods and classes on the fly, the interpreter won't know until runtime whether the calling method has sent an invalid message or not. This is generally considered a Good Thing®, but your mileage and opinions may certainly vary.
In the answer to this SO question Jörg W Mittag says:
There is no such thing as a constructor in Ruby.
I didn't think much of that, until I read the Wikipedia article on constructors, which states:
Immutable objects must be initialized in a constructor.
Since symbols are immutable in Ruby, how are they made? Wikipedia would seem to think they must be made with a constructor, yet Jörg says there are no constructors in Ruby.
I'm fairly new to OOP concepts and programming in general, so it possible I am missing something fairly basic, but from my perspective it there is a contradiction between these sources.
When people say
There is no such thing as a constructor in Ruby.
they mean that there is no special method type corresponding to a constructor, the way there is in C++ and Java.
In Ruby, the initialize method is, by convention, used to initialize a new object. However, it is not a special method -- it's a method just like any other method in Ruby.
Symbols are 'initialized' in some dark inside part of the ruby runtime, that you don't need to worry about.
If you make your own immutable class in ruby, it would have to be initialized in it's "constructor", which in ruby means in it's #initialize method. The initialize method may or may not technically be a constructor, but it's the method that is called when the object is instantiated, which is the point the wikipedia article is making -- since an immutable object can't be changed once created, any state has to be set when it's created, not later.
Wikipedia article calls this 'a constructor', but different languages use different terminology or exact constructs, the wikipedia article wasn't written with ruby in mind. For ruby, "place you can set state on object instantiation" is typically initialize method. (I say 'typically', because you can do all kinds of crazy things in ruby if you try). The wikipedia article is still right that if an object is truly immutable, any setting of state happens to happen on object creation, not afterwords -- that's just the meaning of 'immutable', right?
That's for immutable classes implemented by ruby source code. But good luck finding an 'initialize' method for symbols. They don't work that way. They are just provided by ruby itself, by the runtime, and we don't need to worry about the details.
I'm build a library for generic reporting, Excel(using Spreadsheet), and most of the time I'll be writing things out on the last created worksheet (or active as I mostly refer to it).
So I'm wondering if there's a naming convention for methods that are mostly sugar to the normal/unsugared method.
For instance I saw a blog post, scroll down to Composite, a while ago where the author used the #method for the sugared, and #method! when unsugared/manual.
Could this be said to be a normal way of doing things, or just an odd implementation?
What I'm thinking of doing now is:
add_row(data)
add_row!(sheet, data)
This feels like a good fit to me, but is there a consensus on how these kinds of methods should be named?
Edit
I'm aware that the ! is used for "dangerous" methods and ? for query/boolean responses. Which is why I got curious whether the usage in Prawn (the blog post) could be said to be normal.
I think it's fair to say that your definitions:
add_row(data)
add_row!(sheet, data)
are going to confuse Ruby users. There is a good number of naming conventions is the Ruby community that are considered like a de-facto standard for naming. For example, the bang methods are meant to modify the receiver, see map and map!. Another convention is add the ? as a suffix to methods that returns a boolean. See all? or any? for a reference.
I used to see bang-methods as more dangerous version of a regular named method:
Array#reverse! that modifies array itself instead of returning new array with reversed order of elements.
ActiveRecord::Base#save! (from Rails) validates model and save it if it's valid. But unlike regular version that return true or false depending on whether the model was saved or not raises an exception if model is invalid.
I don't remember seeing bang-methods as sugared alternatives for regular methods. May be I'd give such methods their own distinct name other then just adding a bang to regular version name.
Why have two separate methods? You could for example make the sheet an optional parameter, for example
def add_row(sheet = active_sheet, data)
...
end
default values don't have to just be static values - in this case it's calling the active_sheet method. If my memory is correct prior to ruby 1.9 you'd have to swap the parameters as optional parameters couldn't be followed by non optional ones.
I'd agree with other answers that ! has rather different connotations to me.