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