The following may be a bit of an ‘Advanced NubyGem’ but I think this is an interesting idiom that most people will have to work with.
Sometimes in Ruby you’ll see things, both in core and third party libraries, that look a bit like class names that take arguments.
You may of already seen these in the form of Integer(), Array(), etc.
>> Integer(1) => 1 >> Integer("1") => 1 >> Integer("") ArgumentError: invalid value for Integer: "" from (irb):3:in `Integer' from (irb):3
These weird looking methods are just alternate constructors. They can really come in handy as a way to simplify the most common ways of building a given object, or giving them some different behaviors.
Here is an example from Ruport:
The long way of constructing a Table object:
table = Ruport::Data::Table.new :data => [[1,2,3],[4,5,6]], :column_names => %w[a b c]
This is the shortcut interface:
table = Table(%w[a b c]) << [1,2,3] << [4,5,6]
This is usually less typing and looks a little cleaner. Of course, it doesn't support the same exact options of the original constructor, but that's what we're going for afterall.
How it's done
Implementing these methods is as simple as using capitalized method names. In Ruport, we are currently a little surly and do this right on Kernel so you can get the constructors everywhere:
module Kernel def Table(*args) #implementation here end end
A safer way
Instead of sticking these methods in Kernel, you can play it safe and put them in a module,
this way, they only are available where you include them. For example, if enough people complain, we’ll probably do something like this:
module Ruport::Data::Shortcuts def Table(*args) #.... end end
This way, people would be able to use these shortcuts just in certain classes by including the module in them. If you’re worried about your names conflicting with others, this might be a good idea.
Don’t Overuse Your Shortcuts!
I should fix this problem before I tell folks not to do it, but right now bits of Ruport code use the shortcut methods internally. Unless you have a really compelling reason (other than laziness) to do this, Don’t!
The very thing that makes it ’safe enough’ to stick these shortcuts in core is that a conflict should only break the shortcut. If you use your shortcuts internally in your code, there is a chance of some serious issues if things collide.