Make_collector

Got tired of perpetually writing if-then-else code to accumulate the
results of an iterator and return an array if no block was passed in.
(The somewhat hacked-up gensym class could probably use work - how
threadsafe is Singleton? Would using a class instance variable be
better?)

···

require ‘singleton’

class Gensym
include Singleton

def initialize
@n = 0
end

def next
@n += 1
"G#{@n}".intern
end
end

def gensym
Gensym.instance.next
end

class Module
def make_collector(*args)
args.each {|meth|
oldmeth = gensym
module_eval <<-here
alias #{oldmeth} #{meth}
def #{meth}(*args)
retval = []
#{oldmeth}(*args) {|x|
if block_given?
yield x
else
retval << x
end
}
end
here
}
end
end

class Foo
def initialize
@ary = (1…10).to_a
end

def traverse
@ary.each {|x| yield x}
end

make_collector(:traverse)
end

a = Foo.new
a.traverse {|x| p x}
p a.traverse

Got tired of perpetually writing if-then-else code to accumulate the
results of an iterator and return an array if no block was passed in.
(The somewhat hacked-up gensym class could probably use work - how
threadsafe is Singleton? Would using a class instance variable be
better?)


require ‘singleton’

class Gensym
include Singleton

def initialize
@n = 0
end

def next
@n += 1
“G#{@n}”.intern
end
end

def gensym
Gensym.instance.next
end

Why not simply use some prefix?

class Module
def make_collector(*args)
args.each {|meth|
module_eval <<-EOF
alias_method :_foo_bar_baz#{meth}, :#{meth}
def #{meth}(*args)
retval =
_foo_bar_baz#{meth}(*args) {|x|
if block_given?
yield x
else
retval << x
end
}
end
EOF
}
end
end

···

On Sat, May 17, 2003 at 02:00:35AM +0900, Martin DeMello wrote:

class Foo
def initialize
@ary = (1…10).to_a
end

def traverse
@ary.each {|x| yield x}
end

make_collector(:traverse)
end

a = Foo.new
a.traverse {|x| p x}
p a.traverse


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

I’m an idiot… At least this [bug] took about 5 minutes to find…
Disquieting …
– Gonzalo Tornaria in response to Linus Torvalds’s

Slight mistake…

class Module
def make_collector(*args)
args.each {|meth|
oldmeth = gensym
module_eval <<-here
alias #{oldmeth} #{meth}
def #{meth}(*args)
retval =
#{oldmeth}(*args) {|x|
if block_given?
yield x
else
retval << x
end
}

     retval
···

Martin DeMello martindemello@yahoo.com wrote:

 end
 here

}
end
end

I dunno - for some reason I’m always a bit uneasy about using alias wth
an arbitrary prefix. I haven’t sat down and examined it, but it feels
fragile.

martin

···

Mauricio Fern?ndez batsman.geo@yahoo.com wrote:

Why not simply use some prefix?

class Module
def make_collector(*args)
args.each {|meth|
module_eval <<-EOF
alias_method :_foo_bar_baz#{meth}, :#{meth}