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.
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
attr parent
block.call(self, depth)
root.do_something_in_the_tree {|node, depth| puts “#{’
'*depth}#{node}” }
Thanks,
David
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.
Cheers,
ben