Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get size of cloned lazy enumerator

Tags:

ruby

ruby-2.4

We have an Enumerator::Lazy object

a = [1,2,3].lazy.map {} #=> <Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>
a.size #=> 3
a.clone.size #=> nil

Does anyone have correct explanation of such behaviour ? I know that size returns size of the enumerator, or nil if it can’t be calculated lazily. When we clone object it returns

a.clone #=> <Enumerator::Lazy:<Enumerator::Generator:0x00007fdaa80218d8>:each>
like image 231
Alex Frolov Avatar asked Oct 18 '22 02:10

Alex Frolov


1 Answers

I know that size returns size of the enumerator, or nil if it can’t be calculated lazily.

size for a Enumerator is not necessarily a real thing ( or atleast not what one would think it is) which may be the reason this change was implemented.

For example

[1,2,3].to_enum.size
#=> nil

[1,2,3].to_enum(:each) { 1 }.size #=> 1
#=> 1

or better still

[1,2,3].to_enum(:each) { "A" }.size 
#=> "A" 

When we clone object it returns a.clone #=> <Enumerator::Lazy<Enumerator::Generator:0x00007fdaa80218d8>:each>

This seems to be a change in 2.4 where it appears that it reverts back to the :each method (possibly through enum_for) because in 2.3 the reference to map is retained as is the size. Obviously due to the reversion no iteration has occurred and size cannot be determine in a "lazy" fashion and thus nil

like image 121
engineersmnky Avatar answered Oct 21 '22 04:10

engineersmnky