Issue #11130 has been updated by Usaku NAKAMURA.


Masaki Matsushita wrote:
> Enumerable#countは、実際にイテレーションを回してみて回った数を数える実装となっています。
> pull request ( https://github.com/ruby/ruby/pull/444 )の狙いはEnumerable#to_aの高速化なので、countは不向きです。

Enumerable#countでなく自前の実装があるならそれを使い、そうでないならないものとみなせ、というくらいの意図でした。


> Enumerator#sizeがFixnumを返す場合に限っては、それに依拠して配列のサイズを決めてしまって問題ないのではないかと思います。

自前のコードを漁ってみたら、大昔に書いたRSSパーサの中のクラスがEnumerableをincludeしてsizeを別の意味で定義してたのですが、そいつは整数を返してました。
(RSSのノードを意味するクラスで、eachは子ノードを回すが、sizeは自分を文字列化したときの長さを返していた。)



Yusuke Endoh wrote:
> 議論は #9118 にあります。

おお、ありがとうございます。ははは、同じ内容だ。


> まずは revert に一票です。

あちらでも結論が出てないですし、いったんrevertして、必要ならあちらで議論を再開するのがよさそうですね。



----------------------------------------
Bug #11130: Re: [ruby-changes:38376] glass:r50457 (trunk): * enum.c (enum_to_a): Use size to set array capa when possible.
https://bugs.ruby-lang.org/issues/11130#change-52404

* Author: Kouhei Sutou
* Status: Assigned
* Priority: Normal
* Assignee: Masaki Matsushita
* ruby -v: r50457
* Backport: 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: DONTNEED
----------------------------------------
須藤です。

~~~diff
+    if (NIL_P(size) || size == Qundef) {
+	ary = rb_ary_new();
+    }
+    else {
+	ary = rb_ary_new_capa(NUM2LONG(size));
+    }

~~~
を

~~~c
    if (FIXNUM_P(size)) {
	ary = rb_ary_new_capa(NUM2LONG(size));
    }
    else {
	ary = rb_ary_new();
    }

~~~
とかsizeが返す値が数値じゃなかったらこれまでと同じ挙動にする
ようにしてもらえないでしょうか?

これまでは

~~~ruby
class NonIntegerSizeEnum
  include Enumerable

  def initialize(n)
    @n = n
  end

  def each
    @n.times { |i| yield i }
  end

  def size
    :size
  end
end

NonIntegerSizeEnum.new(100).to_a
~~~

というコードが動いていたんですが、この変更の後からは

> /tmp/b.rb:17:in `to_a': no implicit conversion of Symbol into Integer (TypeError)

というエラーがでるようになってしまって困っています。




-- 
https://bugs.ruby-lang.org/