Enumerable#serially - those nifty functions w/o memory footp

Hello,

I’ve seen many people write things like:

(1…1000000).to_a. # anything that is a huge enumerable can work as an
example
collect{|x| num_appearances(x)}.select{|x|
x.is_norwegian?}.collect{|x| x.paycheck}.each{|x| p x}

I almost wrote something like that myself today.

The problem, of course, is the huge memory footprint - collect,
select, collect each creates a new temporary array to store the
results in.

Here’s a solution to that problem, exchanging it for a bit of speed
(anything that uses those methods could obviously live with that,
otherwise another language or method would be used):

module Enumerable
def serially(&b)
self.collect{|x| *([x].instance_eval(&b)}
end
end

Just beware not to use it with sort or any of the “!” methods or with
sort or sort_by.

Aur

Sorry, found a bug, I’ll need to make it into this:

module Enumerable
def serially(&b)
a = []
self.each{|x| t = ([x].instance_eval(&b); a << b[0] unless b.empty?}
# notice, relevance to “it” discussion that’s currently going on,
just btw
end
end

On 30.05.2007 15:35, SonOfLilit wrote:

Hello,

I’ve seen many people write things like:

(1…1000000).to_a. # anything that is a huge enumerable can work as an
example
collect{|x| num_appearances(x)}.select{|x|
x.is_norwegian?}.collect{|x| x.paycheck}.each{|x| p x}

Just guessing what all this does, but there is of course the obvious
solution:

some_large_enum.each do |x|
x = num_appearances(x)
p x.paycheck if x.norwegian?
end

I almost wrote something like that myself today.

The problem, of course, is the huge memory footprint - collect,
select, collect each creates a new temporary array to store the
results in.

Yes, that’s really an issue.

Just beware not to use it with sort or any of the “!” methods or with
sort or sort_by.

I am not exactly sure I understand what this is supposed to do.´ This
isn’t even compiling properly.

Regards

robert

On Wed, May 30, 2007 at 10:46:33PM +0900, SonOfLilit wrote:

Sorry, found a bug, I’ll need to make it into this:

module Enumerable
def serially(&b)
a = []
self.each{|x| t = ([x].instance_eval(&b); a << b[0] unless b.empty?}

notice, relevance to “it” discussion that’s currently going on, just

btw
end
end

Somehow I don’t think you tested this :slight_smile:

  • You have mismatched parentheses
  • You assign to t, but never use the value
  • you call b twice, once with no arguments, and once with 0 as an
    argument
  • b is a block, but you call #empty? on it

Can you give an example of how this is supposed to be used?

Brian.