R
Richard Dale
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
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