[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Enumerable#to_a can run forever

Benjamin Kudria

12/24/2007 11:48:00 PM

It's possible to implement an each method in a class mixing in
Enumerable that runs forever, and thus causing, for example, to_a to run
forever. One such class is mathn's Prime class:

require 'mathn'
Prime.new.to_a # <- runs forever, never returns

This seems a bit broken to me, and I was writing a program where I
needed the first n primes, or all the primes under 200, for example, so
I re-wrote Enumerable#to_a like so to make my code more idiomatic:

----8<----
module Enumerable
def to_a(n = nil)
result = []
inclusion_condition = true
return result if n.to_i <= 0 and !block_given?
each do |*elements|
elements = elements.first if elements.size == 1
if block_given?
values = result.last
inclusion_condition = yield(*values) unless values.nil?
else
inclusion_condition = n != result.size
end

if inclusion_condition
result << elements
else
result.pop if block_given?
break result
end
end
result
end
end
----8<----

This allows, for example, the following:
Prime.new.to_a(10) # => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] , the first
10 primes
Prime.new.to_a {|prime| prime < 20} # => [2, 3, 5, 7, 11, 13, 17, 19] ,
all the primes under 20

Passed an integer paramater, the code will return an array that long, or
until the Enumerable runs out. Passed a block, it will return an array
of elements, adding elements until the block evaluates to false.

This code surely could use some hacking, refactoring, and possibly bug
fixing. I've made a post[1] on http://refactor... just for that
purpose.

Thoughts?

[1]
http://refactor.../codes/196-enumerable-to_a-with-terminating-conditions

-Ben Kudria
--
http://ben.... | Jabber: ben@kudria.net
--
Posted via http://www.ruby-....