From: benjohn@... Date: 2006-10-04T22:13:56+09:00 Subject: Re: How to DRY this? > 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