In the first part, I’m just going to be covering the basics.
Conventions
Before we start, some coding conventions. Firstly, CamelCase for methods and variable names is out – for Ruby it’s lowercase and underscores all the way – it_is_this_way
, itIsNotThisWay
. Classes and Modules (of which more later) should start with an uppercase letter, but the files can start with a lowercase letter. The only break with this convention is in terms of class and module names – here you camel case should be used. Of course you can use CamelCase everywhere if you want, but it’ll be confusing when calling Ruby code written by other people.
Syntax
Some things you’ll notice straight off – brackets for methods with parameters are optional, so do_stuff(10, 20, 30)
works, as does do_stuff 10, 20, 30
. The current recommendation is to use paranthesis when you have arguments as there is a chance that Ruby 2 might break some method calls without brackets (I’d appreciate some clarification on this!).
Methods and if
blocks use end
to terminate rather than brackets:
[ruby]
def do_stuff
if something
…
elsif something_else
…
end
end
[/ruby]
Classes
Classes in Ruby are similar to classes in Java (we’ll deal with typing later). For example to define a Polygon
class, you do the following:
[ruby]
class Polygon
…
end
[/ruby]
You can also subclass:
[ruby]
class Square < Polygon
[/ruby]
You implement constructors by defining an initialize
method:
[ruby]
def initialize
…
end
[/ruby]
And call them using Polygon.new
, Square.new
etc.
Modules
You define modules using:
[ruby]
module Utils
…
end
[/ruby]
You use modules as mixins using the include
keyword. For example imagine the following:
[ruby]
module Renderer
def draw_line(x,y)
…
end
end
[/ruby]
Your Square
class can then include Renderer
to use the draw_line
method:
[ruby]
class Square < Polygon
include Renderer
end
[/ruby]
Some might argue you could get this using an Abstract base class – and you’d be right. However there are no limits to the number of mixins you can include, whereas you can only have one Abstract base class. Ruby provides several very useful mixins – for example if you define the =
operator (we’ll be covering operators later), by including the comparable
module you get <, <=, ==, >=
, and >
for free.
<h3 id="methods>Methods and visibility
As you’ve already seen, you define a method using def method_name
– if you have parameters, you define it using def method_name(arg1,arg2)
). Ruby does support optional parameters. In Java, you’ll often see code like this:
[java]
void doSomething(String name) {
doSomething(name, null);
}
void doSomething(String name, String description) {
…
}
[/java]
In Ruby you can do:
[ruby]
def do_something(name, description = nil)
…
end
[/ruby]
In Java, where you have protected
, public
, private
and default
visibility, you have protected
, public
, private
in Ruby. private
in Ruby is more like protected
in Java however – it can be called from either the class it was defined in, or subclasses. private
methods however can only be called when using self as the reciever, so if do_stuff
is private:
[ruby]
self.do_stuff #Allowed
do_stuff #Not allowed
[/ruby]
Put more simply, a private method cannot be called in a static context.
Ruby’s protected
methods can be called only in the class itsef or subclasses, but can be called without a reciever as well as with a reciever:
[ruby]
self.do_stuff #Allowed
do_stuff #Allowed
[/ruby]
You have two options when defining method visibility. You can use the visibility keywords to define private/protected/public regions:
[ruby]
protected
def this_is_protected
…
end
private
def this_is_a_private_method
…
end
def this_is_also_private
…
end
[/ruby]
You can also do it on a single line:
[ruby]
def this_is_protected
…
end
def this_is_a_private_method
…
end
def this_is_also_private
…
end
protected :this_is_protected
protected :this_is_a_private_method, :this_is_also_private
[/ruby]
Personally I prefer the first technique.
Next time we’ll be looking at operators, arrays, hashes and perhaps even the Ruby typing system.
- Update 1: Fixed wording in the modules section
- Update 2: Updated methods section thanks to feedback from Curt Hibbs
- Update 3: Fixed typos in the classes and methods sections (thanks Gavri Fernandez)
- Update 4: Fixed typos (thanks Eliot and Alex) and clarified use of camel case (thanks Jon ).
- Update 5 21st April 2006: Fixed up some missing text due to WordPress import. Used new syntax highlighting for code samples
20 Responses to “Ruby For Java (and C#) Programmers, Part 1 – Conventions, methods, modules, and classes”
Sam, this is the only I can seem to contact you please email me.
Thanks for the series, I’ll be watching and reading along.
According to Matz, it is currently recommended that you use paranthesis on method calls:
do_stuff(10, 20, 30)
as there are changes in Ruby 2 that could break some code that omits the paranthesis (I don’t recall specifically what).
Of course when creating domain specific langauges where you want to simulate the introduction of a new keyword, then it makes sense to omit the paranthesis. Since Rails makes heavy use of this idiom, I can’t imagine Matz breaking that in Ruby 2.
Thanks for that Curt.
class Square << Polygon
should be
class Square < Polygon
Gah! Thanks Gavri – I went < crazy for a while there…
And
def do_something(name, description == nil)
should be
def do_something(name, description = nil)
Fixed – thanks for the feedback everyone.
Fixed – thanks for the feedback everyone.
I don’t know what the fixed code was, but the problem with parenthesis is in double calls:
>> $VERBOSE=true
=> true
>> p p 10
(irb):2: warning: parenthesize argument(s) for future version
10
nil
=> nil
>> p 10
10
=> nil
AFAIK This is what is going to be possibly broken, allowing parenthesis just within a single method call at a time (very reasonable imho).
Thanks! I was looking for something like this.
Hi Sam, thanks for the article – very helpful and succint, perfect for Java-heads like me learning Ruby.
I noticed in the last code snippet, that “protected :this_is_a_private_method, this_is_also_private” should be “private: ….”
Great article.
Clarification on CamelCase versus under_score: under_scores are used in all identifiers (methods, variables etc) *except* class names and module names in which case CamelCase should be used.
(These identifiers must start with upper case letters as constants in Ruby are indicated using first letter upper case. Modules and classes are just object like everything else in Ruby, and these objects are bound to constants.)
Thanks for the clarification Jon (and spotting the typo Eliot!) – another update coming up…
Nice entry!
Some more corrections:
[quote]
The current recommendation is to use parameters* when you have arguments […]
[/quote]
should be
[quote]
The current recommendation is to use paranthesis* when you have arguments […]
[/quote]
and later same paragraph:
appreciate – but this is allowed :-).
thanks,
:alex |.::the_mindstorm::.|
nicely done
Thanks all – keep the feedback coming. There are some loose ends from this part I’m going to be covering in part two (more on methods and classes) so I’ll be talking about typing in part three. Let me know if there is anything in particular you’d like to see covered.
keep it up.. i will enjoy this blog 🙂
btw i can’t post with Opera
and the layout is fucked up in IE
.. let me guess you are a firefox user..
Gah – the layout problems are a recent thing (damn dynamic sites) – I think a bit of the sidebar content is pushing things out. Will resolve it asap. And for the record, I’m an IE, Firefox and Safari user – I’ll grab Opera and see what the problem with posting is (which version by the way?).
You got the comments about private methods backward. You show this for private methods:
self.do_stuff #Allowed
do_stuff #Not allowed
But it’s really the other way around:
self.do_stuff # Not Allowed
do_stuff # allowed