magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Posts from the ‘Development’ category

A recent post by Cedric in response to an article by Michael Feathers (danger, community navel gazing alert! Obviously this blog is above such things) casts doubt on the necessity of unit tests.

Michael’s rules on what a unit test is seem overly draconian to some (not being able to touch the filesystem for example – 99% of the time I’d agree, but if I’m testing my FileConfiguration class, what the hell am I supposed to do?) – and despite many other people attempting to define what a unit test is, Cedric’s take on it comes the closest to my own understanding of what a unit test is:

…a unit test is traditionally defined as a set of test that exercises a single class in isolation of all others.

Cedric then goes on to say that 90% of the tests he sees written with JUnit are not unit tests. I for one would be wary of working on those codebases. He also states that he doesn’t care if the test he writes is a unit or functional test – which immediately makes me worry about working on his codebase.

The point that gets missed here is that Unit and Functional tests are not different because of how they work, how long they take or the tools required to make them work, but they are different because they fulfill different roles in development.

Unit tests, because they focus on testing one class and one class only, make it much easier to create highly-focused loosely coupled code, as you create and test a class in isolation of other code. As you have good test coverage at a single class level, you can then safely refactor the class and know you haven’t changed the behavior of the unit. As you are writing code and testing at a small level, you can commit your code more frequently, enabling frequent, smaller-scale integration. If you are testing at a class level, the test themselves become a living document detailing how your code works.

Functional tests are supposed to test slices through your system – from UI to back-end and back if possible. You are asserting that your system conforms to the behavior expected by your users.

Unit tests tend to be fast because they limit the code they test. Functional tests tend to be slow, because they test more code, and also interact with slow components (e.g. databases, browsers, networks etc) but their speed doesn’t define what type of test they are.

Often there is the need to separate fast tests from slow tests – and TestNG’s categorisation of tests is perhaps the first feature of the TestNG that has interested me. But the categorisation is done in order to define fast feedback cycles (e.g. run a quick build on checkin, and longer build on the hour, everyday etc – see Speeding up the build and build pipelining for more details) this should not be used to confuse functional and unit tests. Developers need to understand the different requirements for, and benefits of, these two different types of tests.

Well last night’s inaugural Django and Rails meetup went very well indeed (photos to follow) – apart from the slow start due to most people not knowing each other, and being unsure if the raised eyebrow from someone else in the bar was as a result of them seeing if they were there for the meetup or as a result of wandering into the wrong sort of bar. Photos soon. It was good to meet Simon and Natalie (who came down from Gloster for the event and had to go back by bus), Matt, Tom (who had to get back to paddington for 10) and everyone else. The unfortunate side of the turnout being so good was that I didn’t have enough time to speak to anyone – and with that in mind felt we should make it a monthly thing.

Unless there are any complaints, the venue and time will be the same, Smiths of Smithfield at 7pm. To avoid clashing with other events (well, my monthly pub crawl which happens on the first Tuesday of every month to be exact) I’m suggesting the second Monday of the month – which this time around is the 10th of October. Simon Brunning is going to arrange the London Python meetup for the same time so there’ll be some fresh blood 🙂 As before, leave your comment if you fancy coming along…

There seems to be two different ways to format your dates using Django. The first takes advantage of Python’s built-in strftime, so to format a date according to ISO8601:


mymodel.some_date_field.strftime("%Y%m%dT%H%m")

Giving you a date like 20050819T2031.
<!-more->
Another approach is to format in the templates instead – then you can take advantage of Django’s filters. This formatting is based on the PHP date function circa 4.1 (none of the formatting added in PHP 5.0 seems to be supported) – I assume using Simon Willison’s earlier work. I like the filters, but dislike the fact that I have one type of formatting in my models (and which other Python people will know) and another inside templates. It also doesn’t seem to be as flexible – for example to format a date in the same way as above (with a ‘T’ seperating date and time) I need two filters:



	

{{ mymodel.some_date_field|date:"Ymd" }}T{{ mymodel.some_date_field|date:"Gi" }}

I suppose if it bothers me that much I can always write my own filter…

Just a little reminder – the meetup is still on for the 5th. It’s looking like a good turnout too – the following people have mentioned they may be coming along:

  • Simon Brunning
  • Tom Dyson
  • Matt Biddulph
  • Tom Dunham
  • Matt Mower
  • Sean O’Halpin
  • Tom Ward
  • James Adam
  • xtian
  • Simon Willison
  • Scott Matthewman
  • Will Macdonald
  • Jon Ramsey
  • Ben de Groot
  • Rob M
  • Peter Ferne
  • Peter Cooper
  • Jeremy Keith
  • Tom Armitage
  • Dan Webb
  • Matthew Westcott
  • Neal Todd
  • Helen Bright
  • Victoria Chan
  • Andrew Whitehouse

    …why can’t we all just, get along?

    My post comparing Django and Rails has garnered good response, and has probably set a record for the number of comments left in a single day for this site. What most impressed me (beyond the fact that a few people seemed to like the piece in the first place) is that the comments left didn’t degenerate into a flame war about what was better. That has reinforced what I originally thought – that in the same way Ruby and Python are more similar than disimilar, Django and Rails are more alike than they are different.

    I mentioned at the end of the article that I thought both communities could learn from each other. So, in the spirit of goodwill, I thought it would be nice to have an informal meetup for the local Rails and Django developers in London village. In the style of the successful Python and Java meetups, it’ll involve an evening, a pub, and perhaps some hula hoops.

    I’m interested in all kinds of people coming – those using either Rails or Django commercially or as a hobby, those who think the whole thing sounds like the emperors new framework, those who are open minded and curious, and even those who’ve never coded a line of a dynamic language in their life. Feel free to bring along laptops and give demos. To give people plenty of time (and because there is a bank holiday in the way) I’m suggesting the 5th of September from 7pm, and because I can walk there from work, Smiths of Smithfield (home of many a Java meetup). Please leave a comment if you want to come along!

Since lambasting someone for a less than fair Django and Rails comparison, I’d planned to do my own. To start with, my comparison is based on several days worth of Rails development and about a weekend’s worth of playing with Django, using the (currently four part) tutorial.

I’ve had this reviewed by both Rails and Django developers, but if you think I’ve misrepresented anything or left anything out then feel free to leave a comment and I’ll make sure to put it right.

Background

Rails is framework which emerged from the development of a web application, Basecamp. Django was emerged from the development of the highly successful Lawrence Journal World. Both applications were written in situations and organisations that historically would have ended up being written in Perl or PHP – but ended up being written in Ruby and Python respectively.

The fact that both frameworks were the result of development of specific applications means that both frameworks are focused on supporting those specific types of application. As a framework Rails has been around for little over a year, whereas as a framework in its own right django has only been public for around two months. Neither has yet made it to version 1.0.

Languages

On the face of it, the biggest difference between the two has been the choice of development language. Outside of Japan Ruby has made little impact despite having been around as long as Python – a colleague of mine once said that the number of Python programmers in London probably outnumbered the number of Ruby programmers in Europe and the US and he’s probably not wrong. Anyone having to consider which of the two frameworks is right for them is inevitably going to have to think about the task of hiring people and this may have an impact on their choice.

Ruby does seem to have some more powerful language features – it has slightly better closure support than Python (although perhaps not enough to be a differentiating factor) and the extremely useful mixins. Ruby’s OO support also feels much cleaner. Both support inheritance (Python supports multiple inheritance, which Ruby’s mixins more than make up for). But the requirement that self be passed in to all python instance methods drives me potty.

On the other hand Python has a much cleaner syntax (which given its background is no surprise) – more than once I’ve found myself using a third type of parenthesis in the same Ruby method quite validly, only for me to look back at what I’ve done and feel that I’d regressed to the bad old days of Perl. It would be nice to think that one day a language will come along which manages to add powerful features without making the code look like it’s been rendered with the wrong character encoding.

Ultimately comparing two languages that are so close (they’re certainly more similar to each other than Java or .NET) is going to come down to personal choice or a specific requirement. But for more indepth comparisons you’ll no doubt find many out there on the web.

Requirements and installation

Installing both Rails and Django is fairly easy once you’ve got the relevant interpreter installed. Ruby can make use of the excellent Gems system, which is something Python (and to be fair most other languages including Java) would do well to mimic.

Both also come with their own webserver for development purposes, which is great from a developer’s point of view. There should be anything stopping you from getting both up and running fairly quickly

Deployment options

Both Python and Ruby suffer from a similar global interpreter lock problem – basically neither the Ruby nor Python interpreters are completely thread safe. When running multi-threaded applications a lock has to be acquired by a thread before it can access any objects. That means that both Ruby and Python scale by using multiple instances of the interpreters rather than the Java approach of using multiple threads – as a result the deployment options are fairly similar.

Django’s current recommended deployment is using Apache and mod_python, although there is no reason why fastcgi couldn’t be used, or even an alternate server such as lighttpd (which is TextDrive’s current approach to hosting Rails).

One important point is that Django currently only supports Sqlite, MySql and Postgres (although support for Oracle has already been submitted to the project), whereas Rails supports virtually all the major relational databases.

Caching

Django’s heritage as a framework supporting large, high-volume websites shows through clearly in the built-in support for a variety of caching options. Rails’ own caching doesn’t seem as flexible. With Django multiple caching backends are supported (in memory, memcached, or DB) coupled with supporting caching at multiple levels – either for a whole site, a specific page or fragment (like Rails), or even a specific object.

Setting up a project

Both frameworks generate your project structure for you. Django actually has separate concepts of Project and Application (of which more later). Rails goes a little further – it also generates a build file and stub tests (I won’t call them Unit tests as Rails does, because they’re not). There is nothing to stop you testing Django of course – it’s just as testable as Rails – however it would be nice to get some guidance on how to do it. My feeling is many people new to testing are more likely to do it with Rails because it’s built right in and it’s well documented.

Adding models

In Rails, you define a table that represents your model, and then generate the stub code to create a Rails model that binds to the table. You are then free to build upon the stubs. With Django, you define your model in Python code, and have Django generate (and even execute) the schema for your model.

The fact that your Python code can be the canonical reference for your models means understanding can be simplified. It can seem odd to be adding code to a Rails model and not know exactly what attributes your model has without referring to the database schema. The fact that Django can generate the SQL from you model also leads to flexibility in development – for example a developer can use Sqlite which is fast use and trivial to setup, but deploying onto MySql or Postgres is easy as you can regenerate the SQL for your target database from the Python code – that the SQL for both databases might need to be different is hidden from you.

Early on your model will be constantly changing – I’ll often find myself writing some Rails code, need to add a new attribute to a model, have to change my (DB-specific) schema. With Django I change my model and regenerate the SQL. The only minor annoyance is that there is no equivalent of a model-specific SQL refresh – something that could drop a specific model’s tables and regenerate the needed SQL automatically. Instead you have to have the admin script dump out the SQL to the command prompt and run it in yourself.

Django’s generation of schema also extends to creating lookup tables for many-to-many relationships.

The downside to having Django generate the SQL schema is that there is more work involved in supporting databases – currently only MySQL, Postgres and Sqlite are supported, although I’d be highly surprised if support for other databases wasn’t on the way.

Django does seem to offer the ability to reverse-engineer models from an existing schema, although I don’t have information as to how sophisticated this is (for example to what extent it can determine inter-model relationships).

Another thing to note is that unlike Rails Django doesn’t allow you to manage your own transactions (although it is going to be added). I’ve not found myself needing it in my Rails or Django work to date, although as a J2EE programmer not having the ability to control this if I need to is a minor concern for me.

Interaction with the Database

Both Django and Rails have taken the decision to bind models to the database. Methods to save, delete or lookup objects are called on the models themselves. Neither specifically stops you from providing proper separation, but if you do you’re on your own. Going forward it will be interesting to see if either Rails or Django start providing the ability to have a clean repository layer as nicely as they do the current DB access, although it will probably require both of these frameworks to be used in more complex situations than they are currently.

One nice thing Django offers is the ability to write your own SQL in the model to access attributes. Rails does nothing to stop you calling SQL directly, but the fact that with Django you are doing this custom lookup in the same place as the definition of the other attributes (whereas with Rails it would be split between the schema and Rails model) results in something much cleaner.

Projects and Applications

A nice touch with Django, and another example of the environment in which it was developed, is that there is a project in which you can have pluggable applications. This should hopefully lead to smaller (Rails-style) apps being created, reused and integrated easily into a larger Django projects. This was something that was demonstrated wit LJWorld, with new parts being added incrementally without a need to deploy the whole site.

Controllers and URLs

With both Rails and Django URLs are mapped directly to code. Rails automatically generates stub controllers to map to the scaffolding (of which more later), whereas with Django you have to create them yourself.

With Django you use regular expressions to define URL’s that bind to your python code. That makes it much easier to create RESTful URLs – in fact all of the tutorials reinforce this. The fact that you have RESTful URLs happens to make controlling code simpler is just an added bonus.

By default Rails gives you URL’s in the form controller/method – but these can be edited using the routes.rb file to give you proper RESTful (or not) URL’s. Unlike Django’s pseudo mod_rewrite approach, Rails uses Ruby code to handle routing, which depending on your point of view could be considered more readable.

The URL to code mapping can be specified either for a whole project or (more likely) for a single application.

Templating options

Both Django and Rails template using embedded Python or Rails code (like using Java scriptlets in JSP pages). Much more work has been put into Rails’ helper code – Ruby code you can use to generate HTML constructs – its excellent Ajax support being one example. Django does make it fairly easy to swap in other templating options if required (such as Zope’s Template Attribute Language, or perhaps Clearsilver). I’m less savvy on alternate templating options available for Rails – although obviously if you used something else you’d have to do without many of the helper methods available.

Administration and User management

Django’s administration interface is simply excellent. Unlike Rails’ scaffolding views, it is not designed to be viewed by everyone (being an Admin console), but unlike the scaffolding it is perfectly functional and you could imagine making use of it without alteration in a production application.

The administration console is password protected – you can generate a superuser account using the command line admin script. Once you’ve logged in you can add more users and even groups – Django automatically generates permissions for both the admin functions and your models which can be assigned to a group.

You can also add new model instances in the same way as Rails scafolding, but the view is much better. You have nice popups and shortcuts for date and time fields, dropdown lists for one-to-many relationships, and multi-select lists for many-to-many relationships all provided without any developer interaction.

Rails does have a measure of user administration in the form of the add-on salted login hash generator, but despite some hard work by the developers it does seem problematic and nowhere near as slick as Django.

So which is right for you?

I said at the start that the two frameworks were developed as a result of two very different applications – and most of the differences between the two are a result of this. If you are developing a simple (in a domain model sense) application where you want to use Ajax to deliver a great UI, Rails is probably for you. If however you want to develop an entire site with different types of applications within it – then Django’s plugable applications and general approach might be what you’re after. Equally, the better user and administration side of Django favours portal style applications – this is something you’ll have to do yourself if you want to use Rails.

There is scope for both frameworks to learn from each other, and I still have a question around how well Rails will scale (in terms of the size of the site, not number of hits) – Django has already proved it is capable of this with LjWorld.com. Likewise it will be interesting to see if Django can or even wants to make the use of Ajax as simple as it is with Rails (although work is already progressing along these lines), or if the more powerful language features of Ruby will prove the deciding factor.

Personally, given my own current projects I’ll be spending some more time with Django – but all that means is that it is one more tool that will sit alongside Ruby, Rails and J2EE in my particular toolbox. And just like Java web frameworks before, I fully expect to see more and more web frameworks based on dynamic languages (such as Nitro or SeaSide) start to gain more visibility and yet more options. It seems we’re going to be spoilt for choice.

It’s been a while since I’ve had to unleash the angry kitten, but it seems that the OpenAdaptor developers have rather inadvisably irked me, to the extent that I’ve withheld the kitten’s food for two days now, to make the ensuing carnage all the more…well, carnagy.

To start with, I like the concept and some of the architecure behind Open Adaptor. It’s a fine arhictecture – it’s no suprise that plenty of other APIs out there have come up with similar solutions to the same problems. The JBI spec obviously owes a lot to OpenAdaptor. That said its implementation frequently makes me want to have a few minutes with the developers, a pair of pliers and a blowtorch.

Creating sinks, pipes and sources

Let’s start with the fact that to create anything you’re pratically forced to use property files. No Inversion Of Control for you my son, oh no – here we have a special init method, which is not a constructor because…well, it’s called init, its enforced by the API, and it takes a Properties object. The only benifit over being able to construct objects the way you want seems to be it made it easy for the developers to use property files (I hope for the next version they at least look at spring). That makes tesing so much fun. Please note the sarcasm.

JARs not built using debug information

Yes, you heard me right. Here was I, thinking we lived in the age of high-speed internet connections. But in fact it seems internet bandwidth is so tight that the developers considered providing debug information so we could work out for which odd reason an Adaptor fails a luxury.

Errors that are not errors – or might be

So when your adaptor fails with no clear reason why – well, what should you do? That’s right, turn on debug – chances are a debug message will detail why your adaptor failed. Even better, sometimes the error message will be vague, for example the one that tells me that either my JNDI server may be unavailable, or that it is there but the thing I want isn’t, or that it is there and the thing I want is there, only I might be missing a class, only it won’t tell me what class that might be. That is an error message that can be really fun to work with. And I don’t mean the good type of fun either, I mean the achingly irritating kind of fun that can only result in me hurting my foot kicking office furniture.

A nice idea crippled by an allergy to interfaces

OpenAdaptor has a rather sensible and useful (sounding) feature called message hospitals. Normally, if a message causes an exception the app shuts down. You can however choose to configure a message hospital which will capture all messages which throw an exception – but only an exception of a given type. However by “type” OpenAdaptor means “class” – you have to throw a checked PipelineException. This is bad enough – I now have to have a top-level catch throwable clause that rethrows PipelineException – but the constructor doesn’t even take a root cause. Quite why a simple ExceptionType interface couldn’t be used I have no idea.

Conclusion

OpenAdaptor has a sound premise, but it’s implementation needs bringing up to date. A full rewrite in the form of OpenAdaptor 3 is underway – get involved.

Package dependencies in Pasta

Package dependencies in Pasta

Today on my current project I had to spend some time creating a client JAR file for use by downstream systems. I needed to keep the JAR as small as possible, with (more importantly) no external JAR dependencies.

There are tools out there for dependency analysis, such as IBM’s Structural Analysis for Java (aka Smallworlds), Compuware’s Pasta or the open source JDepend. As nice as these tools are, they are for analysis and the gathering of metrics. As I’ve mentioned before, unless ‘good metrics’ are in some way enforced by the build process, it becomes very easy for even automatically gathered metrics to be ignored.

JDepend can be run via Ant, but just like Emma or Findbugs the information gathered is used for reporting purposes – it is not capable of failing a build because someone has introduced an invalid dependency between packages.

Japan is a tool which comes with an Ant plugin that will fail a build if your code violates the allowed package dependencies. For example, our downstream systems only need to use classes in the client package – I don’t want to have to include any other code in the client JAR file. So in a Japan config file I place the following code:

Missing

Now if any of the classes in client include any other packages in my codebase, the build will fail. It’s important to note that Japan requires that you define all your dependencies at the package depth you define (the package-depth="4<a href="http://www.c2.com/cgi/wiki?AcyclicDependenciesPrinciple" <2>> means that all source code in com.company.app.xxx and below will be checked) – so for example if our gui package depended on util and client, I’d have to add the line:

Missing

By defining these configurations you can quickly discover circular dependencies) – for example if to get the build passing you find yourself defining something like this:

Missing

You know something is up. The other thing I like about Japan is the fact that because I can now enforce sensible package dependencies, I feel better about spending some time cleaning our packages up, safe in the knowledge that we won’t backslide (assuming no-one goes and sticks everything in one giant package of course). There was one little problem I had though – I had to disable transitive dependency checking as it caused a stack overflow error, but I think once we remove our existing circular dependencies that should sort itself out. I still of course like to have tools like Pasta to help me define acceptable inter-package dependencies, but I feel much happier having Japan in the build just in case I start getting sloppy :-).

I’m taking a break from my recent series of articles on Ruby (see Parts one, two and three of Ruby for Java (and C#) programmers) to revisit the subject of mocking in Ruby. My recent overview of the currently available mocking tools lead me to discuss a better syntax for the next mocking API.

One of my aims when talking about a new syntax for a mocking API was in order to make expectations more readable – and more usable as a living document detailing how the code being tested actually works. As has already been discussed, Ruby’s flexible syntax makes it particularly suitable for the creation of Domain Specific Languages – and I think we can do much better than the existing API’s (or even the more mature JMock) in moving towards a DSL for mocking.

My original idea was to steal from the structure of JMock:

mockObject = Mock.new(ClazzToMock)
mockObject.expects(:someOperation).
  with(arg1, arg2).
  willReturn(someReturn)

To which Carlos (correctly) pointed out that I should make use of Ruby’s built-in language constructs – he proposed using hashes to avoid chaining calls together:

mock_obj = Mock.new(ClassToMock)
mock_obj.expects(
:do_stuff,
:with => [arg1, arg2],
:returns => someReturn
)

The obvious difference here is that the API cannot enforce the expectation to be written in a way that makes sense, as I could just as easily write:

mock_obj = Mock.new(ClassToMock)
mock_obj.expects(
:do_stuff,
:returns => someReturn,
:with => [arg1, arg2]
)

Also of note is that (when we get a decent one) IDE’s won’t be able to help you construct your expectations – this was part of the aims behind JMock’s structure.

Nat countered with the use of a mocking mixin, and using blocks as the expectations:

mock = Mock.new “exampleMock”
expect 1 { mock.do_something(eq(10), !null) }
expect 3..4 { mock.something_else(eq(“hello”) }

In EasyMock terminology, when you define the expectation in a block, it is in a record state – that is you are registering the calls that you expect to be made. In EasyMock, you then have to call replay before the mock can be used. This really doesn’t help readability (JMock gets around this by having a different object for recording expectations to the one used as the mock). With Nat’s approach, the mock is only in replay mode within an expect.

Taking this further, I cannot see why multiple expectations on multiple mocks couldn’t be defined inside a single expect call:

expect {
  mock1.halve(eq(10)).returns(5)
  mock1.double(eq(5)).returns(10)
  mock2.insult.returns("Boogers!")
}

Before (more importantly if) I decide work on this, I want to try and get some consensus of opinion as to what would make a sensible syntax, so feedback on Nat’s approach is appreciated!

Following on from Part 2, we look at two of Ruby’s most important collection classes, Hashes and Arrays, as well as have a brief look at the typing system.

Update 1: Fixed typo, thanks Anjan – any day now I’ll stop writing this stuff so late at night I’m too tired to proof read.

Update 2: Fixed blatant syntax error – thanks Chris

Arrays

We’ve already seen a little of one of Ruby’s built in types, the array. You can work with them much like Java’s Array:

[ruby]
array = [4, 6.0, “Hello”]
array0 —> 4
array1 —> 6.0
array2 —> “Hello”
array.length—> 3
[/ruby]

Where in Java we’d need a for loop to iteratie through the elements in an array, in Ruby we can use a number of built-in array method each. For example to print out the string value of each item in the array:

[ruby]
array.each { | item | puts item.to_s }
[/ruby]

The array class makes use of the Enumerable module – any class which implements each and @ can include the @Enumerable module, getting a variety of helpful methods for free:

[ruby]
array = [4, 6, 8, 10]
array.find_all { | item | item => 8 } —> [8, 10]
array.include?(6) —> true
array.include?(“Fish”) —> false
array.partition { | item | item [[4, 6], [8, 10]]
array.min —> 4
array.collect { | item | item – 2} —> [2, 4, 6, 8]
[/ruby]

Hashes

Another of Ruby’s collection types is Hash. Like Java’s Hashtable or HashMap classes – a construct which uses a key to index an object. To access the values in a hash, you use the element reference construct, []:

[ruby]
ages = { “sam” => 28, “norman” => 60, “fred” => 45 }
ages[“sam”] —> 28
ages[“fred”] —> 45
ages[“jane”] —> nil
ages[“sam”] = 30
ages[“sam”] —> 30
[/ruby]

Hash also implements Enumerable:

[ruby]
ages = { “sam” => 28, “norman” => 60, “fred” => 45 }
ages.each { | name, age | puts ”#{name} is #{age} years old”}
ages.sort —> [[“fred”, 45], [“norman”, 60], [“sam”, 28]]
ages.include?(“sam”) —> true
ages.include?(“jane”)—> false
ages.partition { | name, age | age [ [[“fred”, 45], [“sam”, 28]], [[“norman”, 60]] ]
[/ruby]

We’ll be looking at more advanced uses of both Arrays and Hashes later on.

“Quack quack” – the Ruby typing system

There is a saying – “If it walks like a duck and talks like a duck, it must be a duck”. In Ruby, you don’t say something is a duck – you make it act like a duck. In Java, you hang a nice big sign around it’s neck saying “duck”, then go about implementing the duck methods. On the face of it, this isn’t a big difference. Compare:

public interface Duck {
  void waddle(int distance);

  String speak();
}

	

public class Mallard implements Duck {

public void waddle(int distance) { ... } public void speak() { return "Quack!"; } }

public class Pintail implements Duck {

public void waddle(int distance) { ... } public String speak() { return "Quack!"; } }

And in Ruby:

class Mallard
  def waddle(distance)
    ...
  end

  def speak
    return "Quack!"
  end
end

	

class Pintail

def waddle(distance) ... end def speak return "Quack!" end end

Now lets imagine a Dog class, who can also speak:

public interface Dog {
  String speak();
}

	

class Dalmation implements Dog {

public String dog() { return "Woof!"; } }

And in Ruby:

class Dog
  def speak
    puts "Woof!"
  end
end

Now lets imagine a Naturalist, who’s job it is to study the sights and more importantly the sounds of the wildlife around him. If we just wanted to study ducks, then we could define a simple interface:

public interface Naturalist {
  void study(Duck duck);
}

	

public class WildlifeReporter implements Naturalist {

public void study(Duck duck) { tapeRecorder.record(duck.speak()); } }

And in Ruby:

class Naturalist
  def study(duck)
    tape_recorder.record(duck.speak)
  end
end

Now if we wanted our Naturalist to also study a Dog, in Java we’d either have to define two methods – one study that takes a Duck, and another that takes a Dog – but more likely we’d define another interface (say, Animal) from which both Dog and Duck derive, and redefine study to take that new interface. With Ruby, our Naturalist is the same for both – all it cares about is that whatever gets passed into study defines a speak method.

Now implementing the Animal doesn’t seem like a big deal, and in this (highly contrived) example, it isn’t. But you can see how you’ll quickly end up with a number of type definitions, all defining the same operations, just so you can work in a generic fashion with a variety of objects. The typical solution to this in Java is to have many very fine-grained interfaces (in some cases you’ll even see many interfaces only implementing a single method).

We’ll be looking more at the Ruby typing system in later parts.

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.