spec/examples/sieve_spec.rb in agent-0.1.0 vs spec/examples/sieve_spec.rb in agent-0.9.0

- old
+ new

@@ -1,143 +1,149 @@ -require "helper" +require "spec_helper" describe "sieve of Eratosthenes" do # http://golang.org/doc/go_tutorial.html#tmp_353 it "should work using Channel primitives" do # send the sequence 2,3,4, ... to returned channel - def generate - ch = Agent::Channel.new(name: 'generator', type: Integer) + def generate(channels) + ch = channel!(Integer) + channels << ch + go!{ i = 1; loop { ch << i+= 1} } - go do - i = 1 - loop { ch << i+= 1 } - end - return ch end # filter out input values divisible by *prime*, send rest to returned channel - def filter(in_channel, prime) - out = Agent::Channel.new(name: "filter-#{prime}", type: Integer) + def filter(in_channel, prime, channels) + out = channel!(Integer) + channels << out - go do + go! do loop do - i = in_channel.receive + i, _ = in_channel.receive out << i if (i % prime) != 0 end end return out end - def sieve - out = Agent::Channel.new(name: 'sieve', type: Integer) + def sieve(channels) + out = channel!(Integer) + channels << out - go do - ch = generate + go! do + ch = generate(channels) loop do - prime = ch.receive + prime, _ = ch.receive out << prime - ch = filter(ch, prime) + ch = filter(ch, prime, channels) end end return out end # run the sieve n = 20 nth = false + channels = [] - primes = sieve + primes = sieve(channels) result = [] if nth n.times { primes.receive } - puts primes.receive + puts primes.receive[0] else loop do - p = primes.receive + p, _ = primes.receive if p <= n result << p else break end end end result.should == [2,3,5,7,11,13,17,19] + channels.each(&:close) end it "should work with Ruby blocks" do # send the sequence 2,3,4, ... to returned channel - generate = Proc.new do - ch = Agent::Channel.new(name: 'generator-block', type: Integer) + generate = Proc.new do |channels| + ch = channel!(Integer) + channels << ch - go do + go! do i = 1 loop { ch << i+= 1 } end ch end # filter out input values divisible by *prime*, send rest to returned channel - filtr = Proc.new do |in_channel, prime| - out = Agent::Channel.new(name: "filter-#{prime}-block", type: Integer) + filtr = Proc.new do |in_channel, prime, channels| + out = channel!(Integer) + channels << out - go do + go! do loop do - i = in_channel.receive + i, _ = in_channel.receive out << i if (i % prime) != 0 end end out end - sieve = -> do - out = Agent::Channel.new(name: 'sieve-block', type: Integer) + sieve = Proc.new do |channels| + out = channel!(Integer) + channels << out - go do - ch = generate.call + go! do + ch = generate.call(channels) loop do - prime = ch.receive + prime, _ = ch.receive out << prime - ch = filtr.call(ch, prime) + ch = filtr.call(ch, prime, channels) end end out end # run the sieve n = 20 nth = false + channels = [] - primes = sieve.call + primes = sieve.call(channels) result = [] if nth n.times { primes.receive } - puts primes.receive + puts primes.receive[0] else loop do - p = primes.receive + p, _ = primes.receive if p <= n result << p else break end end end result.should == [2,3,5,7,11,13,17,19] + channels.each(&:close) end end