Bug #14845
closed
Added by igaiga (Kuniaki Igarashi) over 6 years ago.
Updated over 6 years ago.
Description
endless Rangeで次のケースで困ることがあります。
- 1..nilはendless Rangeになる
- endless Rangeはto_aすると返ってこなくなる
- 1..変数 のケースで意図せずendless Rangeになる可能性があり、そのときto_aすると返ってこなくなる
Ruby 2.5.1 では 1..nil はArgumentError (bad value for range) になります。
たとえば、 1..nil がendless Rangeではなくエラーになればこの問題は解決します。
Info¶
Files
Related issues
1 (1 open — 0 closed)
現状の挙動はそれはそれで便利そう※なので、early failure と便利さとのトレードオフです。どっちがいいでしょうね。
※たとえば SQL の DSL で count: (min..max)
という Range を書いたとき、max = nil
にするだけで「上限なし」を表現できるという使い方が考えられます。(1..nil)
がエラーになると、count: max ? (min..max) : (min..)
とかいう記述が必要になり、DSL としては終了です。
問題を to_a
に限れば、(1..nil).to_a
や enum.cycle.to_a
のように、明らかに停止しない to_a
呼び出しを例外にするという解決もありえると思います(「明らかに停止しない」が本当に正しいかどうか自信が持てないところですが)。
うっかり (1..nil)
を作ってしまったというリアルな例などがあると、議論が捗りそうです。
- Status changed from Open to Closed
Applied in changeset trunk|r63646.
range.c: prohibit (1..nil)
Now endless range can be created by either a literal (1..)
or explicit
range creation Range.new(1, nil)
. [Bug #14845]
This change is intended for "early failure"; for example,
(1..var).to_a
causes out of memory if var
is inadvertently nil.
- Status changed from Closed to Assigned
- Assignee set to matz (Yukihiro Matsumoto)
- Status changed from Assigned to Closed
Applied in changeset commit:ruby-git|48de2ea5f9b9067779acb0f7f76e5f879f2b42c0.
range.c: prohibit (1..nil)
Now endless range can be created by either a literal (1..)
or explicit
range creation Range.new(1, nil)
. [Bug #14845]
This change is intended for "early failure"; for example,
(1..var).to_a
causes out of memory if var
is inadvertently nil.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63646 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
I meant (1..).to_a
to raise an exception (for apparent infinity loop), not prohibiting 1..nil
'.
Matz.
- Status changed from Closed to Assigned
matz (Yukihiro Matsumoto) wrote:
I meant (1..).to_a
to raise an exception (for apparent infinity loop), not prohibiting 1..nil
'.
Matz.
Sorry for my misunderstanding. I reverted r63646.
I'm attaching a patch for Range#to_a
that raises an RangeError for an endless range, and that calls super to Enumerable#to_a
for a normal range.
別チケットにした方が良いのかもしれませんが、関連するのでここにコメントしておきます。
Range.new(1)
のように終端を省略できるようにするのはどうでしょうか?
endless range の時は exclude_end を指定できても違いがないようなので、現状では問題がなさそうに思います。
beginless などの可能性を考えるとキーワード引数も受け付けるようにして、 Range.new(begin: 1, endless: true)
や Range.new(begin: 1, end: 9, exclude_end: true)
のようにかけると良いかもしれません。
- Status changed from Assigned to Closed
Applied in changeset trunk|r63714.
range.c: Range#to_a now raises RangeError if it is endless
Fixes [Bug #14845]
- Related to Misc #17637: Endless ranges with `nil` boundary weird behavior added
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0