Quick singleton question

Hi,

In a structure I'm building, I need to be able to add children (of the same
class) to an object, and have the child object know who its parent is. So I
can do obj.instance_variable_set(:@parent,parentobj), but that doesn't
create the accessor for me, so I still need to do

class << child
    def parent
        @parent
    end
end

That's not really all that onerous, and I can always predefine attr_reader
for :parent in the main class to save the second step, but it lead me to
wondering if there is a 'nice' way to add an instance variable and its
accessor all at once to an object, because that will probably come in handy
one day.

Initially I wanted to do

class << child
    def parent
        parentobj
    end
end

but obviously that will fail since parentobj is out of scope.

Anyway, that's it. :slight_smile:

ben

Ben,

Try:
class Dude
  attr parent
  attr kids

  def initialize(parent)
    @parent = parent
    @kids = []
    parent.add_kid(self) unless parent.nil?
  end

  def do_something_in_the_tree(depth = 0, &block)
    @kids.each {|kid| kid.do_something_in_the_tree(depth + 1, &block)}
    block.call(self, depth)
  end

  protected
  def add_kid(the_kid)
    @kids << the_kid
  end
end

Kids know their parent. Parents know their kids. I threw in a way to
recursively walk the tree... so you can do something like:
root.do_something_in_the_tree {|node, depth| puts "#{' '*depth}#{node}" }

Thanks,

David

···

On 6/22/06, ben@iagu.net <ben@iagu.net > wrote:

Hi,

In a structure I'm building, I need to be able to add children (of the
same
class) to an object, and have the child object know who its parent is. So
I
can do obj.instance_variable_set(:@parent,parentobj), but that doesn't
create the accessor for me, so I still need to do

class << child
    def parent
        @parent
    end
end

That's not really all that onerous, and I can always predefine attr_reader
for :parent in the main class to save the second step, but it lead me to
wondering if there is a 'nice' way to add an instance variable and its
accessor all at once to an object, because that will probably come in
handy
one day.

Initially I wanted to do

class << child
    def parent
        parentobj
    end
end

but obviously that will fail since parentobj is out of scope.

Anyway, that's it. :slight_smile:

ben

--
--------
David Pollak's Ruby Playground
http://dppruby.com

Hi David,

I was actually fishing for the best way to add the instance_variable and
accessor at runtime in case I need it another day, but your code below is
nicer than mine for this particular static class, thanks a lot. I was using
a child array and instance_variable_set in add_child (by default assume no
parent) whereas you're assuming a parent param to initialize by default,
which is probably cleaner. I especially like the recursive tree-walk that
takes a block. Thanks. :slight_smile:

Cheers,

ben

···

-----Original Message-----
From: David Pollak [mailto:pollak@gmail.com]
Sent: Friday, June 23, 2006 12:10 PM
To: ruby-talk ML
Subject: Re: Quick singleton question

Ben,

Try:
class Dude
  attr parent
  attr kids

  def initialize(parent)
    @parent = parent
    @kids = []
    parent.add_kid(self) unless parent.nil?
  end

  def do_something_in_the_tree(depth = 0, &block)
    @kids.each {|kid| kid.do_something_in_the_tree(depth + 1, &block)}
    block.call(self, depth)
  end

  protected
  def add_kid(the_kid)
    @kids << the_kid
  end
end

Kids know their parent. Parents know their kids. I threw in a way to
recursively walk the tree... so you can do something like:
root.do_something_in_the_tree {|node, depth| puts "#{'
'*depth}#{node}" }

Thanks,

David