magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

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”

  1. kaz

    Sam, this is the only I can seem to contact you please email me.

    Reply
  2. Curt Hibbs

    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.

    Reply
  3. riffraff

    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).

    Reply
  4. Eliot Sykes

    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: ….”

    Reply
  5. Jon Tirsen

    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.)

    Reply
  6. Alex Popescu

    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::.|

    Reply
  7. Sam Newman

    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.

    Reply
  8. simonsays

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

    Reply
  9. Sam Newman

    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?).

    Reply
  10. Adam Jenkins

    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

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS

%d bloggers like this: