Ruby For Java (and C#) Programmers, Part 1 - Conventions, methods, modules, and classes

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.

>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

This entry was posted on Monday, June 13th, 2005 at 1:44 pm and is filed under General, Ruby. You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.

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

Have your say





Fields in bold are required. Email addresses are never published or distributed.

Some HTML code is allowed:

URIs must be fully qualified (eg: http://www.domainname.com) and all tags must be properly closed.

Line breaks and paragraphs are automatically converted.

Please keep comments relevant. Off-topic, offensive or inappropriate comments may be edited or removed.