[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to DRY this?

Peter Szinek

10/4/2006 1:06:00 PM

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.rubyra...

22 Answers

benjohn

10/4/2006 1:14:00 PM

0

> 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
> ...

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


Ken Bloom

10/4/2006 1:18:00 PM

0

On Wed, 04 Oct 2006 22:05:41 +0900, Peter Szinek 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 ;-)
>
> ...
> 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.

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}

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...
I've added a signing subkey to my GPG key. Please update your keyring.

Jean Helou

10/4/2006 1:18:00 PM

0

On 10/4/06, Peter Szinek <peter@rubyrailways.com> 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 ;-)
>
> ...
> 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.rubyra...
>
>

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

David Holroyd

10/4/2006 1:19:00 PM

0

On Wed, Oct 04, 2006 at 10:05:41PM +0900, Peter Szinek 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

--
http://david.holr...

Jean Helou

10/4/2006 1:20:00 PM

0

On 10/4/06, benjohn@fysh.org <benjohn@fysh.org> 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 ;-)
> >
> > ...
> > 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
> > ...
>
> 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

great !! I like yours better, now I wish I hadn't tried :)

jean

benjohn

10/4/2006 1:30:00 PM

0

> 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).




M. Edward (Ed) Borasky

10/4/2006 1:35:00 PM

0

Peter Szinek 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 ;-)
>
> ...
> 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.rubyra...
>
>

A couple of obvious (to me, anyhow) questions:

1. You are "pushing" elements and element names. Are you "pulling" or
"popping" them somewhere else?

2. If you just pushed the element name, could you retrieve the element
from its name?

3. 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?


Simon Kröger

10/4/2006 7:07:00 PM

0

Peter Szinek 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


Farm1

10/10/2012 8:24:00 AM

0

"Gillard=Dudd in a frock." <flatulantdingo@deadspam.com> wrote in message
news:rt7a781pf6ldnof2a115umctudfjjlq2c3@4ax.com...
> On Wed, 10 Oct 2012 18:02:08 +1100, "Farm1" <Here@there.sometimes>
> wrote:
>
>>She sure did go. But about time too IMO. For too long she's let him get
>>away with too much crap. Loathesome man that he is.
>
> Poor diddums.
>
> Don't you like him?

No. I've said repeatedly that I find him loathesome. Woud you like me to
state it once more or can you remember that?


bringyagrogalong

10/10/2012 9:00:00 AM

0

"Farm1" <H...@there.sometimes> wrote:
> "Gillard=Dudd in a frock." babbled:
> > "Farm1" <H...@there.sometimes> wrote:
> >>
> >> She sure did go. But about time too IMO. For too long she's let him get
> >> away with too much crap.  Loathesome man that he is.
>
> > Poor diddums.
>
> > Don't you like him?
>
> No.  I've said repeatedly that I find him loathesome. Woud you like me to
> state it once more or can you remember that?

That's a big ask. LOL

"Never had the opportunity of even finishing school."
?http://tinyurl.c...

Best for the learned among us to shun the imbecile.

--------------

Julia Gillard's internationally lauded towelling of Abbott:
http://tinyurl.c...