magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Update: Fixed bonehead misunderstanding on my part, thanks to Daniel spotting it, and a typo thanks to riffraff.

I left a few loose ends from Part 1, so I’m moving a discussion on the type system to Part 3 so I can revisit methods and classes.

Returning from methods

In the normal way, you can return from a method using the return keyword:

[ruby]
def calculate_sum(a, b)

return a + b
end
[/ruby]

By default however, the return value of any ruby method will be the result of the last line of execution, so the above method could be written as:

[ruby]
def calculate_sum(a, b)

a + b
end
[/ruby]

Personally, I prefer to use explicit return calls as it reduces ambiquity as to how a method should be used.

Class and Instance variables

Last time we didn’t talk about instance variables. Unlike Java, you have no need to define instance variables before you use them. Instead, when you need one, use it with the @ prefix, like so:

[ruby]
def initialize(name)

@name = name
end
[/ruby]

To define class variables (the equivilent of Java static variables) you use two @ symbols:

[ruby]
def initialize(name)

@name = name
@@last_creation_time = DateTime.now
end
[/ruby]

Variables without the @ prefix are considered local variables, and are only available within the scope of the block they were defined in.

unless

As I showed before, you can construct simple if/elsif/else blocks like so:

[ruby]
if some_value = = 0


elsif some_value = = 1

else

end
[/ruby]

Like Java, you can use ! to negate a boolean expression, or you can use != to denote not-equals. Ruby also adds the unless keyword – so rather than:

[ruby]
if some_value != 0


end
[/ruby]

You can write the following instead:

[ruby]
unless some_value = = 0


end
[/ruby]

Use of unless can help make code more readable, especially when using methods with a ? suffix, as we’ll show in the next section.

Special Method Suffixes

Ruby allows the use of two special suffixes for method names – ? and !. Any method followed by a ? is assumed to have a boolean return type, for example:

[ruby]
if task.completed?


end
[/ruby]

And rather than the ugly !task.completed?:

[ruby]
unless task.completed?


end
[/ruby]

The second suffix is used to denote destrcutive methods – that is those methods which affect the target of the method. For example, imagine we have a Sqaure class, which has two methods, flipHorizontal and flipHorizontal! – the first method should define a non-desctructive call which returns a copy of the Sqaure, whereas the second form should rotate the object itself.

Operators

In Java, operators such as +, -, * and the like all have meanings defined in the language itself. You can use + to concat strings, or you can use it for normal arithmetic, but that is about it. In Ruby, you can define the behaviour of these operators for each class. You’ll find yourself using this often when defining comparison operators. In Java, you’d implement the Comparable interface, which defines compareTo – returning -1, 0 or +1 if the object was less than, the same as or more than some other object. You would also have to seperately define equals() for equality, and the definition of == always asserts object identity. In Ruby, you can implement the <=> operator, which does the same job as Java’s Comparable, except that it can be used as an operator. For example if we wanted to define comparison in terms of a classes name:

[ruby]
def (rhs)

return name rhs.name
end
[/ruby]

And we could then do:

[ruby]
some_object some_other_object
[/ruby]

Include the Comparable module in your code however, and you automatically get the <, <=, = =>, > operators for free, as they can all be defined in terms of the result of the <=> operator. The fun doesn’t stop there – you can also define the [] oeprator to provide array indexing of your objects:

[ruby]
class RecordCollection

def [] (index)
return @records[index]
end
end
[/ruby]

And you can even define []= to provide a way to assign arrays:

[ruby]
def []= (array)

logger.debug(“Taking array #{array}”)
@records = array
end

collection = RecordCollection.new
collection[] = [Record.new(“Some Record”), Record.new(“Some other Record”)]
collection0 => Record.new(“Some Record”)
collection1 => Record.new(“Some other Record”)
[/ruby]

In Part three we’ll finally look at the Ruby typing system, and might have time to look at arrays and hashes.

6 Responses to “Ruby For Java (and C#) Programmers, Part 2 – Operators, methods, and more on classes”

  1. Daniel Berger

    “The use of the ? suffix is not simply something to make the code more readable – if you don’t specify the ? suffix your methods will return either 1 or 0, both of which equate to true in the ruby world.”

    Not true.

    # perfectly legal
    def hello?
    return “hello”
    end

    The “?” and “!” are a convention. There is no builtin enforcement of any kind. Of course, violating this convention is a short path to a slew of nasty emails, but I digress.

    – Dan

    Reply
  2. simonsays

    Version 8.01
    Build 7583
    Platform Win32
    System Windows XP

    This was a post from opera.. so i guess its either fixed or it was a problem with opera.

    Reply
  3. Aslak Hellesoy

    Nice ones Sam,

    One topic that I think could be interesting for a future blog in the same series would be collections (Hash, Enumerable and Array) and how they compare with their Java counterparts.

    Especially how to iterate over them, insert and access values, and also how to use the very powerful join, collect, inject, each methods (these are my favourites, there are many more)

    Reply
  4. Sam Newman

    I’ll probaby introduce arrays and hashes in part three, but will save the juicy stuff for part 4. Oh, and I’ll try and grab a copy of Opera this weekend and give the site the once over.

    Reply
  5. riffraff

    I guess you typoed “comparable”, it should be uppercased since it is a module.

    I also think it should be highlighted how mixins+operator ovwerloading in this particular case avoid code duplication and possible errors in respect to java, i.e.

    a < b
    instead of
    a.compareTo(b)== -1

    Reply

Leave a Reply to Daniel Berger Cancel 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: