From: gabriele renzi Date: 2005-05-28T20:15:20+09:00 Subject: Useless hack of the saturday morning 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 [] 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