Useless hack of the saturday morning

G

gabriele renzi

Hi gurus and nubys,

this morning I stumbled across the Autrijus Tang journal[1],
which was showing this nifty piece of code:


say [~] (-> @c is copy {gather {
while @c[0] { for @c ->
{take(.shift)} } }
}(['Joec','utrk','shle','te6r',' r .','a h.','nPa.'].map:{[split "",$_]}));

in perl6 the [<something>] is the reduce metaoperator, and -> is the
equivalent of "proc".
The hard thing was understanding what gather/take are supposed to do.
A little investigation yielded explanation[2], they seem to be some kind
of accumulating construct a-la inject. In the tradition of the
perl6->ruby port such as junctions, .= operator and so on I tried
implement it.


Oh, and here is the translated JAPRH

proc{|c|p gather{c.each{|x|take x.shift}while
c[0][0]}.join}.call ['Joedh','utr a','shlRc',
'te6uk',' r be','a ayr.','nPn .' ].map{|x|x.split ''}

And down is the implementation[3]
[1] http://use.perl.org/~autrijus/journal/24919

[2] http://search.cpan.org/~dconway/Perl6-Gather-0.04/Gather.pm

[3]
class Gatherer
attr :gathered
def take(arg)
@gathered||=[]
@gathered<< arg
end
end

def gather &blk
c=Gatherer.new
c.instance_eval &blk
c.gathered
end

if __FILE__ == $0
require 'test/unit'

class TestGatherer < Test::Unit::TestCase
def ok(x, y)
assert_equal x.to_a,y
end
def test_take
l= gather { for i in 1..10: take i end}
ok 1..10, l
end
def test_take2
l= gather { for i in 1..10: take i end; take 99}
assert_equal (1..10).to_a+[99],l
end

def test_gathered
l= gather {for i in 1..10: take i end; take 99 unless gathered}
ok 1..10,l
end

def test_gathered_empty
l= gather {take 99 unless gathered}
ok 99,l
end

def test_gathered_pop
l= gather {for i in 1..10: take i end; gathered.pop }
ok 1..9,l
end
end
end
 
G

gabriele renzi

Christian Neukirchen ha scritto:
That's very nice and useful (I often wished for it), but goo already
had it for a long time. :) It is called "packing" there, see
http://people.csail.mit.edu/jrb/goo/manual.46/goomanual_29.html

wow, I always thought GOO was cool, it seem I need to investigate it
more deeply :)
I think the implementation with instance_eval can be a bit surprising,
maybe [Dynamic Variables][1] could do that better.

yup, instance_eval is an hack, but I liked the idea of just allowing
#take inside #gather, which I don't have Idea how to reproduce withouth
it. Using DynaVars seem definitely a cool hack, anyway :)
 
M

murphy

what about a more Ruby-like extension:

class Array
def add
yield self
self
end
end

# simple
a = [].add do |a|
a << 1
a << 2
a << 3
end
p a

# Fibonacci
b = [1,1].add do |a|
15.times { a << a[-1] + a[-2] }
end
p b

Array#inject may do as well.
 
J

James Edward Gray II

I think the nice thing about packings is that they don't need to
reference the array variable... your code is no improvement to just
appending to the array directly, IMHO.

In that case, how are gather/packing an improvement? They require
more typing than just appending to an Array.

I guess I just don't "get it". <shrugs>

James Edward Gray II
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,478
Latest member
ReginaldVi

Latest Threads

Top