Mark Hubbart
11/5/2004 7:40:00 PM
Hi,
On Fri, 5 Nov 2004 23:05:36 +0900, David A. Black <dblack@wobblini.net> wrote:
> Hi --
>
> On Fri, 5 Nov 2004, Mark Hubbart wrote:
>
> > Well, after some interesting sidetracked thoughts, I came up with this form:
> >
> > [1,2,3,4].do_first{|n| print n}.then_rest{|n| print ", ",n}
> > 1, 2, 3, 4 ==>[1, 2, 3, 4]
> >
> > Then this quickly hacked implementation, using singleton methods to
> > turn the first block into a proxy quasi-enumerable object.
>
> Hmmmm.... it's a bit of a stretch to "get" that the first call is
> going to return its own block (with or without modifications :-)
> There's no technical reason for it not to, but I think it's kind of
> unidiomatic.
I'm not claiming this is good code - I know it's not. But it was fun
to write :) I think it shows how flexible Ruby is. The end syntax is
very readable, though the method chaining isn't. And the method names
leave something to be desired.
> > module Enumerable
> > def do_first(&block)
> > class << block
> > def then_rest
> > first_done = nil
> > @enum.each do |arg|
> > yield arg if first_done
> > first_done ||= [self[arg]]
> > end
> > end
> > end
> > this = self
> > block.instance_eval{@enum = this}
> > block
> > end
> > end
>
> Don't forget that there's no Enumerable#[], so this would not work for
> all Enumerables.
I didn't use Enumerable#[]
"one\ntwo\nthree".do_first{|n| print n.chomp}.then_rest{|n| print ", ",n.chomp}
one, two, three ==>"one\ntwo\nthree"
(1..3).do_first{|n| print n}.then_rest{|n| print ", ",n}
1, 2, 3 ==>1..3
I did use #[] on a block...
> For what it's worth (maybe not much), here's another possible way to
> go about it:
>
> module M
> def do_both(b1, b2, n=1)
> current = b1
> i = 1
> each do |e|
> current.call(e)
> i += 1
> current = b2 if i > n
> end
> end
> end
>
> arr = [1,2,3,4,5] .extend(M)
> arr.do_both(lambda {|x| print x }, lambda {|x| print ", #{x}" })
The challenge I took was to figure out a way to pass two blocks,
without lambda/proc/Proc.new. I did that by using method chaining and
a proxy object. I agree that the idea wasn't worth much, except maybe
as an exercise. And I'm not suggesting the OP show this to his friend
:)
Anyway, please forgive my ugly code :) I'll leave this now...
cheers,
Mark
>
> David
>
> --
> David A. Black
> dblack@wobblini.net
>
>