Issues with inheritance

I'm building a large system that needs to have a data structure of
things that look and act similar to one another in a kind of
composition tree. Take a look at my small scale test code below:

class Main
  def main
    #instantiate objects
    three = Child3.new
    two = Child2.new
    one = Child1.new
    #build tree
    two.addNode three
    one.addNode two
    #execute tree
    one.execute "Who is "
  end
end

class Parent
  #Has some composing nodes
  @nodes
  #Init code
  def initialize
    @nodes = Array.new
  end
  #add a node to object
  def addNode node
    @nodes << node
  end
  #Generalized execute code
  def execute str
    puts str + self.to_s
    @nodes.each {|node| node.execute str}
  end
end

class Child1 < Parent
  #The same a parent in this scenerio but has other functionality not
illustrated here
end

class Child2 < Parent
  #The same a parent in most cases, needs to do "extra" in execute
calls
  def execute str
    puts str + self.to_s
    #@nodes.each {|node| node.execute "Batman?"} <---This works but its
really ideal for code recycling
    #str = "Robin" <---This actually causes subsequent levels to print
Robin instead of Batman? or Who is
    super.execute "Batman?"
  end
end

class Child3 < Parent
  #The same a parent in this scenerio but has other functionality not
illustrated here
end
#Just so I can execute my Test.rb easy in eclipse, not really
important
if __FILE__ == $0
  Main.new.main
end

When I designed the code I expected what would print out would be:
     >Who is <Child1>
     >Who is <Child2>
     >Batman? <Child3>
But I get:
     >Who is <Child1>
     >Who is <Child2>
     >Who is <Child2>
     >Who is <Child3>
     >Error

The first problem I see is that when I call super.execute it seems to
want to ignore my argument and favor of the argument I gave at the
hight level of scope. (If I do str = "Robin" in Child2's execute but
still call super.execute("batman") it prints ">Robin" in subsequent
levels.) The second is that Child2 somehow calls execute on itself
once before digging into the next level of the tree, then at the last
level it tries to call it on an empty array which goes against the
program logic. I'm not new to programming, I've probably built this
exact same thing in Java, but I am new to Ruby. Whats wrong with what
I'm trying to do?

Thanks in advance!

The first problem I see is that when I call super.execute it seems to
want to ignore my argument and favor of the argument I gave at the
hight level of scope. (If I do str = "Robin" in Child2's execute but
still call super.execute("batman") it prints ">Robin" in subsequent
levels.) The second is that Child2 somehow calls execute on itself
once before digging into the next level of the tree, then at the last
level it tries to call it on an empty array which goes against the
program logic. I'm not new to programming, I've probably built this
exact same thing in Java, but I am new to Ruby. Whats wrong with what
I'm trying to do?

In Ruby, you just call super() to call the parent method. There are three
use cases for super:

* Implicit args: `super` -- this calls the parent method with the same
arguments as the current method call.
* No args: `super()` -- the explicit empty parens mean call the parent
method with no arguments, whatever the current method was called with.
* Explicit args: `super(arg1, arg2 ...)` -- calls the parent method with the
given arguments.

Hope that helps.

···

--
James Coglan
http://jcoglan.com

You want super("Batman") here.
super calls the superclass's method of the same name as the current method
with the same arguments as passed to the current method.
super(args) calls the superclass's method with the arguments specified
So what your line does it calls the superclass's method with the arguments
passed to the current method and then calls execute on the result of that.

HTH,
Sebastian

···

Am Montag 20 Juli 2009 17:41:06 schrieb Juston Davies:

                super.execute "Batman?"

You nailed it. I tip my hat to you. I also figured out why child2
looked like it invoking itself, that was a perception error on my
part. Thanks!

···

On Jul 20, 9:45 am, James Coglan <jcog...@googlemail.com> wrote:

> The first problem I see is that when I call super.execute it seems to
> want to ignore my argument and favor of the argument I gave at the
> hight level of scope. (If I do str = "Robin" in Child2's execute but
> still call super.execute("batman") it prints ">Robin" in subsequent
> levels.) The second is that Child2 somehow calls execute on itself
> once before digging into the next level of the tree, then at the last
> level it tries to call it on an empty array which goes against the
> program logic. I'm not new to programming, I've probably built this
> exact same thing in Java, but I am new to Ruby. Whats wrong with what
> I'm trying to do?

In Ruby, you just call super() to call the parent method. There are three
use cases for super:

* Implicit args: `super` -- this calls the parent method with the same
arguments as the current method call.
* No args: `super()` -- the explicit empty parens mean call the parent
method with no arguments, whatever the current method was called with.
* Explicit args: `super(arg1, arg2 ...)` -- calls the parent method with the
given arguments.

Hope that helps.

--
James Coglanhttp://jcoglan.com