On Patrick Logan's blog he gives a ruby example in discussing design
trade-offs implementing a visitor/decorator pattern with search trees that
are a mixture of elephants and boxes of elephants. 

http://martinfowler.com/bliki/CourtesyImplementation.html

But I just couldn't work out what the code meant at first - it took me about
5 mins of staring at it before the penny dropped..

# Ruby
class Node
end

class Box < Node
  def initialize 
    @children = []
  end
  def << aNode
    @children << aNode
  end
  def num_elephants
    result = 0
    @children.each do |c|
      if c.kind_of? Elephant
        result += 1
      else
        result += c.num_elephants
      end
    end
    return result
  end
end

class Elephant < Node
end

My problem was the the method:

  def << aNode
    @children << aNode
  end

I wondered what is this strange new ruby syntax? But as soon as I saw it
meant this I could follow the code:

  def <<(aNode)
    @children << aNode
  end

It's like one of the 'Escher mind teasers' where you seen a cube from one
perspective, and then suddenly your brain flip-flops to another one.

Are there any rules of thumb for when it's a good idea to leave out the
brackets and when to use them?

He says it's bad style to use 'if c.kind_of? Elephant', and instead it's
better to expect each node to return a number of elephants. His improved
example expects every node to respond to 'num_elephants', but he makes no
check and so there would be a method_missing execption thrown for a
non-elephant/non-box thing.

I think the second example would be improved by a respond_to? check, but
what if you expected 'elephant aware nodes' to return you a total elephant
weight? Has anyone suggested adding a 'conforms_to?' check in ruby that
checks that an instance will respond_to? an Array of method name symbols?

Then you could query whether a node responds to both 'num_elephants' and
'elephant_weight' by passing an Array like this:

if c.conforms_to? [:num_elephants, :elephant_weight]..

so you could define the protocol as a constant:

ELEPHANT_PROTOCOL = [:num_elephants, :elephant_weight]

if c.conforms_to? ELEPHANT_PROTOCOL..

-- Richard