7

次のコード スニペットは、Mac OS X の 1.8.7 では正常に動作しますが、Ubuntu の 1.8.6 では動作しません。なんで?回避策はありますか?

1.8.7 で動作:

$ ruby --version
ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0]
ltredgate15:eegl leem$ irb
>> 6.times.map {'foo'}
=> ["foo", "foo", "foo", "foo", "foo", "foo"]
>>

しかし、1.8.6 にはありません:

# ruby --version
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-linux]
Ruby Enterprise Edition 20090610
# irb
irb(main):001:0> 6.times.map {'foo'}
LocalJumpError: no block given
        from (irb):1:in `times'
        from (irb):1
irb(main):002:0> 

なぜ違いがあるのですか?1.8.6 の回避策は何ですか?

4

4 に答える 4

17

times1.8.7 以降では、ブロックなしで呼び出された場合のような反復子メソッドは列挙子を返します。1.8.6では、あなたがしなければならない

require 'enumerator'
6.enum_for(:times).map {...}

または、この特定のユースケースでは、単純に行うことができます (0...6).map {...}

于 2010-05-02T21:27:14.877 に答える
6

Ruby 1.9 ではライブラリが変更され、反復を行う関数がブロックなしで呼び出された場合に Enumerator オブジェクトが返されるようになりました。他の多くの言語機能も変更され、言語全体を改善するために、Ruby 1.8.x と Ruby 1.9 の間で互換性が失われることは広く知られていました。ほとんどの人は、これがあまりにも苦痛だとは思いませんでした。

Ruby 開発チームは、Ruby 1.8.7 を、Ruby 1.9 で導入されたライブラリ機能の一部を追加する移行リリースにする必要があると判断しました。彼らはこの決定に対して多くの批判を受け、多くのエンタープライズ Ruby ユーザーは Ruby 1.8.6 で Rails を実行し続けました (そして今もなお多くが残っています)。なぜなら、彼らは 1.8.7 で導入された変更が大きすぎてリスクが大きすぎると感じているからです。それでも 1.8.7 は残っており、反復関数が Enumerator を返すようにすることは、組み込まれた機能の 1 つです。

1.8.6 には存在しない、1.8.7 で見られるのはこの移行機能です。

sepp2k の答えは良い回避策を提供します。その数に追加することはあまりありません。

于 2010-05-02T21:46:10.967 に答える
1

Ruby1.8.7では多くの変更が導入されています。Ruby 1.8.6でそれらを使用したい場合は、単に

require 'backports'

それでおしまい。これにより、1.9.1と今後の1.9.2の多くのメソッドが提供されますrequire 'backports/1.8.7'が、1.8.7の変更だけ、または必要なバックポートだけでも可能です。require 'backports/1.8.7/integer/times'

于 2010-05-03T13:57:51.933 に答える
1

1.8.6 は指定されたブロックで #times を生成するため、1.8.7 は Enumerator オブジェクトを返すため、保持して Enumerable を実装できます。

于 2010-05-02T21:34:24.160 に答える