[#31647] [Backport #3666] Backport of r26311 (Bug #2587) — Luis Lavena <redmine@...>

Backport #3666: Backport of r26311 (Bug #2587)

13 messages 2010/08/07

[#31666] [Bug #3677] unable to run certain gem binaries' in windows 7 — Roger Pack <redmine@...>

Bug #3677: unable to run certain gem binaries' in windows 7

10 messages 2010/08/10

[#31676] [Backport #3680] Splatting calls to_ary instead of to_a in some cases — Tomas Matousek <redmine@...>

Backport #3680: Splatting calls to_ary instead of to_a in some cases

10 messages 2010/08/11

[#31681] [Bug #3683] getgrnam on computer with NIS group (+)? — Rocky Bernstein <redmine@...>

Bug #3683: getgrnam on computer with NIS group (+)?

13 messages 2010/08/11

[#31843] Garbage Collection Question — Asher <asher@...>

This question is no doubt a function of my own lack of understanding, but I think that asking it will at least help some other folks see what's going on with the internals during garbage collection.

17 messages 2010/08/25
[#31861] Re: Garbage Collection Question — Roger Pack <rogerdpack2@...> 2010/08/26

> The question in short: when an object goes out of scope and has no

[#31862] Re: Garbage Collection Question — Asher <asher@...> 2010/08/26

Right - so how does a pointer ever get off the stack?

[#31873] Re: Garbage Collection Question — Kurt Stephens <ks@...> 2010/08/27

On 8/26/10 11:51 AM, Asher wrote:

[#31894] Re: Garbage Collection Question — Asher <asher@...> 2010/08/27

I very much appreciate the response, and this is helpful in describing the narrative, but it's still a few steps behind my question - but it may very well have clarified some points that help us get there.

[#31896] Re: Garbage Collection Question — Evan Phoenix <evan@...> 2010/08/27

You have introduced something called a "root node" without defining it. What do you mean by this?

[#31885] Avoiding $LOAD_PATH pollution — Eric Hodel <drbrain@...7.net>

Last year Nobu asked me to propose an API for adding an object to

21 messages 2010/08/27

[#31947] not use system for default encoding — Roger Pack <rogerdpack2@...>

It strikes me as a bit "scary" to use system locale settings to

19 messages 2010/08/30

[#31971] Change Ruby's License to BSDL + Ruby's dual license — "NARUSE, Yui" <naruse@...>

Ruby's License will change to BSDL + Ruby's dual license

16 messages 2010/08/31

[ruby-core:31812] Re: [Backport #3715] Enumerator#size and #size=

From: Benoit Daloze <eregontp@...>
Date: 2010-08-21 14:15:41 UTC
List: ruby-core #31812
Hi,

On 18 August 2010 22:02, Marc-Andre Lafortune <redmine@ruby-lang.org> wrote:
> It would be useful to be able to ask an Enumerator for the number of times it will yield, without having to actually iterate it. [...]
> This would print out "Progress: 1 / 20", etc..., while doing the stuff.

That seems cool, indeed.

> *** Proposed changes ***
>
> * Enumerator#size *
>
> call-seq:
> .size > int, Float::INFINITY or nil
> .size {block} > int
>
> Returns the size of the enumerator.
> The form with no block given will do a lazy evaluation of the size without going through the enumeration. If the size can not be determined then +nil+ is returned.

Interesting, though I do not feel INFINITY to be the right answer if
it is a loop (but yes, it should obviously be bigger than anything you
compare to).

> The form with a block will always iterate through the enumerator and return the number of times it yielded.
>
> 1..100).to_a.permutation(4).size # => 94109400
> oop.size # => Float::INFINITY
>
>  = [1, 2, 3]
> .keep_if.size # => 3
>   => [1, 2, 3]
> .keep_if.size{false}  => 3
>   => []
>
> 1, 2, 3].drop_while.size # => nil
> 1, 2, 3].drop_while.size{|i| i < 3}  => 2

What is the interest compared to Enumerable#count ? (also, #size with
a block does not feel natural)

> a = [1, 2, 3]
> a.keep_if.count # => 3
> a # => []

Here the result is identical.

> [1, 2, 3].drop_while.count # => 1

Here it is different, and your method behaves strangely.
The block is yielded 3 times, but your method returns 2 ?

And if you wanted the size of the resulting Array, it seem more obvious to do:
[1,2,3].drop_while { |i| i < 3 }.size # => 1

> * Enumerator#size= *

Having a mutator on Enumerator does not make sense to me, as
previously mentioned by others.
--

However, it is really interesting to know the times an enumerator will yield.

I believe checking for nil is really not beautiful in the code, so I
think it would be nicer if it actually use the block form if it can
not be determined directly.
But this could introduce unwanted side-effects (the #drop_while is an example).
These side-effects should be known, and I do not see any real use for
destructive method with #size, do you ?

About infinite enumerator, it should just yield forever (so calling #each).

I would then propose that Enumerable#count (without block) use this
code to give directly the times it would yield, or if it can not, do
the real iteration like now.

--
And this seems to be already supposed in the documentation of #count:
  Returns the number of items in enum, where #size is called if it
  responds to it, otherwise the items are counted through enumeration.

So, these enumerators should just provide #size, and it should work.

However, it does not behave like that:
> a = (1..1000000000000).to_enum # => #<Enumerator: 1..1000000000000:each>
> def a.size; 3 end
> a.size # => 3
> a.count # => take ages
Defining on the class (Range) does not work either.

So it seems to be a problem with the implementation (in enum.c, line
~122): it does not check if it #respond_to?(:size):
It calls #each with count_all_i() as a block, because there is no
block and no argument.
count_all_i() being a simple block which just increment a counter (memo).

I believe Enumerable#count should respect its documentation, and that
your work would help to implement #size on the Enumerator which sizes
can be known it immediately. Then we would have a consistent behavior,
already described in the documentation !

What do you think ?

Regards,
B.D.

In This Thread