Hello,
I have two very similar code snippets in two different methods, and I am
absolutely sure there is some nice way to DRY them in Ruby… I am still
a noob when comes to Ruby idioms so I’d appreciate some help 
...
while element.class != Hpricot::Doc do
path.push element.name
element = element.parent
end
...
and
…
while element.class != Hpricot::Doc do
path.push element
element = element.parent
end
…
i.e. in the first snippet I am pushing element’s names, and in the
latter the elements themselves.
Thanks,
Peter
http://www.rubyrailways.com
end
...
and
…
while element.class != Hpricot::Doc do
path.push element
element = element.parent
end
…
Pull out the loop logic in to another method…
def traverse_up(element)
while element.class != Hpricot::Doc do
yield(element)
element = element.parent
end
end
The two cases now become:
traverse_up(element) {|e| path.push e,name}
and
traverse_up(element) {|e| path.push e}
Additional comments:
It may (or may not) make sense for the traverse_up method to be a member
of element’s class.
You might like to provide an additional, optional argument, that can be
used to control loop termination…
def traverse_up(element, terminate_at = Hpricot::Doc)
while !(terminate_at === element) do
yield(element)
element = element.parent
end
end
(I’ve also changed the way that element’s class is checked here - but
classes of Hpricot::Doc will also match and terminate the loop).
Cheers,
Benj
On 10/4/06, Peter S. [email protected] wrote:
end
i.e. in the first snippet I am pushing element’s names, and in the
latter the elements themselves.
Thanks,
Peter
http://www.rubyrailways.com
interesting question …
def element_pusher(root_element, attribute=nil)
while element.class!=Hpricot::Doc do
pushie = attribute.nil? ? element : element.send(attribute.to_sym)
path.push pushie
element = element.parent
end
path
end
good ?
I don’t have time to mockup something to test it but
path.push(attribute.nil? ? element : element.send(attribute.to_sym))
might even work …
jean
jean
On Wed, Oct 04, 2006 at 10:05:41PM +0900, Peter S. wrote:
Hello,
I have two very similar code snippets in two different methods, and I am
absolutely sure there is some nice way to DRY them in Ruby… I am still
a noob when comes to Ruby idioms so I’d appreciate some help 
how about (untested)…
def element_and_each_ancestor(element)
while element.class != Hpricot::Doc do
yield element
element = element.parent
end
end
...
while element.class != Hpricot::Doc do
path.push element.name
element = element.parent
end
...
element_and_each_ancestor(element) do |el|
path.push el.name
end
and
…
while element.class != Hpricot::Doc do
path.push element
element = element.parent
end
…
element_and_each_ancestor(element) do |el|
path.push element
end
i.e. in the first snippet I am pushing element’s names, and in the
latter the elements themselves.
ta,
dave
On 10/4/06, [email protected] [email protected] wrote:
end
Pull out the loop logic in to another method…
and
Cheers,
Benj
great !! I like yours better, now I wish I hadn’t tried 
jean
On Wed, 04 Oct 2006 22:05:41 +0900, Peter S. wrote:
end
i.e. in the first snippet I am pushing element’s names, and in the
latter the elements themselves.
Option 1: don’t. It’s a very small snippet of code.
Option 2:
def dopush
while element.class!= Hpricot::Doc do
path.push(yield(element))
element = element.parent
end
end
The first snippet becomes
dopush {|e| e.name}
The second snippet becomes
dopush {|e| e}
jean wrote
great !! I like yours better, now I wish I hadn’t tried 
Well, thanks, but don’t let that put you off (or I’ll wish I hadn’t).
It’s quite interestesting to look at the different approaches. The four
suggestions have three different approaches, and two of the approaches
are very similar (utilisation of yield).
Peter S. wrote:
Hello,
I have two very similar code snippets in two different methods, and I am
absolutely sure there is some nice way to DRY them in Ruby… I am still
a noob when comes to Ruby idioms so I’d appreciate some help 
If you had this:
def ancestors element
…
while element.class != Hpricot::Doc do
path.push element
element = element.parent
end
path
end
...
while element.class != Hpricot::Doc do
path.push element.name
element = element.parent
end
...
would become: ancestors(element).map{|a|a.name}
and
…
while element.class != Hpricot::Doc do
path.push element
element = element.parent
end
…
would become: ancestors(element)
i.e. in the first snippet I am pushing element’s names, and in the
latter the elements themselves.
Thanks,
Peter
cheers
Simon
Peter S. wrote:
end
i.e. in the first snippet I am pushing element’s names, and in the
latter the elements themselves.
Thanks,
Peter
http://www.rubyrailways.com
A couple of obvious (to me, anyhow) questions:
-
You are “pushing” elements and element names. Are you “pulling” or
“popping” them somewhere else?
-
If you just pushed the element name, could you retrieve the element
from its name?
-
Is there some reason you need two loops up the chain? Could you do
while element.class != Hpricot::Doc do
path.push [element.name => element]
element = element.parent
end
or something similar?