これは...
いつまで続くかわからないシリーズである.
学習テストの成果は以下のリポジトリで管理している.
ということで
がちゃ
今日のメソッドガチャは以下の通り.
$ bundle exec ruby gacha.rb クラス: Enumerator メソッド: peek メソッド: rewind メソッド: each_with_index
この中から Enumerator#peek と Enumerator#rewind 及び Enumerator#each_with_index について学習テストしていく.
Enumerator#peek
以下, ドキュメントより引用.
「次」のオブジェクトを返しますが、列挙状態を変化させません。 Enumerator#next のように 現在までの列挙状態に応じて「次」のオブジェクトを返しますが、 next と異なり列挙状態を変更しません。 列挙が既に最後へ到達している場合は、StopIteration 例外を発生します。
irb で動作確認.
irb(main):009:0> a = [1, 2, 3] => [1, 2, 3] irb(main):010:0> e = a.to_enum => #<Enumerator: [1, 2, 3]:each> irb(main):011:0> e.peek => 1 irb(main):012:0> e.peek => 1 irb(main):013:0> e.peek => 1 irb(main):014:0> e.next => 1 irb(main):015:0> e.peek => 2 irb(main):016:0> e.peek => 2 irb(main):017:0> e.next => 2 irb(main):018:0> e.peek => 3 irb(main):019:0> e.peek => 3 irb(main):020:0> e.next => 3 irb(main):021:0> e.peek Traceback (most recent call last): ... StopIteration (iteration reached an end)
- Enumerator#peek だけ実行しても, 「次」のオブジェクトは返さない (= Enumerator#next と異なり列挙状態は変更されない)
- Enumerator#next と比較すると使いドコロが分からない...スイマセン
テストコード.
# file name: 8.rb require 'minitest/autorun' require "minitest/reporters" Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new] class GakushuTest < Minitest::Test def setup a = [1, 2, 3] @e = a.to_enum end def test_peek_1 assert_equal @e.peek, 1 end def test_peek_2 @e.next assert_equal @e.peek, 2 end def test_peek_3 @e.next @e.next assert_equal @e.peek, 3 end def test_peek_exception @e.next @e.next @e.next assert_raises StopIteration do @e.peek end end end
テスト実行.
$ bundle exec ruby 08.rb Started with run options --seed 14812 GakushuTest test_peek_2 PASS (0.00s) test_peek_1 PASS (0.00s) test_peek_3 PASS (0.00s) test_peek_exception PASS (0.00s) Finished in 0.00095s 4 tests, 4 assertions, 0 failures, 0 errors, 0 skips
Enumerator#rewind
以下, ドキュメントより引用.
列挙状態を巻き戻します。 next メソッドによる外部列挙の状態を最初まで巻き戻します。 self を返します。 内包するオブジェクトが rewind メソッドを持つとき(respond_to?(:rewind) に 真を返すとき) は、その rewind メソッドを呼び出します。
irb にて動作確認.
irb(main):001:0> a = [1, 2, 3] => [1, 2, 3] irb(main):002:0> e = a.to_enum => #<Enumerator: [1, 2, 3]:each> irb(main):003:0> e.next => 1 irb(main):004:0> e.rewind => #<Enumerator: [1, 2, 3]:each> irb(main):005:0> e.next => 1 irb(main):006:0> e.next => 2 irb(main):007:0> e.rewind => #<Enumerator: [1, 2, 3]:each> irb(main):008:0> e.next => 1
- Enumerable なオブジェクトにおいて, 列挙状態を巻き戻している
- ざっくり言うと, next で進めたオブジェクトを最初に戻すメソッド...これも, 使いドコロがイマイチ解らない...スンマセン
テストコード. rewind すると, 1 に巻き戻ることを期待する.
# file name: 8.rb require 'minitest/autorun' require "minitest/reporters" Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new] class GakushuTest < Minitest::Test def setup a = [1, 2, 3] @e = a.to_enum end def test_rewind_1 @e.next @e.next @e.rewind assert_equal @e.next, 1 end def test_rewind_2 @e.next @e.next @e.next @e.rewind assert_equal @e.next, 1 end end
テスト実行.
$ bundle exec ruby 08.rb Started with run options --seed 32833 GakushuTest test_rewind_1 PASS (0.00s) test_rewind_2 PASS (0.00s) Finished in 0.00150s 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
Enumerator#each_with_index
以下, ドキュメントより引用.
要素とそのインデックスをブロックに渡して繰り返します。 self を返します。 ブロックを省略した場合は、 要素とそのインデックスを繰り返すような Enumerator を返します。
irb で動作確認.
irb(main):003:0> ['a', 'b', 'c'].each_with_index do |n, index| irb(main):004:1* p [n, index] irb(main):005:1> end ["a", 0] ["b", 1] ["c", 2] => ["a", "b", "c"]
Enumerable なオブジェクトから要素とそのインデックスを返す. たまに使う.
テストは以下の通り. どんなテストを書けば良いのか思いつかなかったので, 以下のようなテストで. インデックスは 0 から始まる点に注意が必要だと思ったので.
# file name: 8.rb require 'minitest/autorun' require "minitest/reporters" Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new] class GakushuTest < Minitest::Test def setup a = [1, 2, 3] @e = a.to_enum end def test_each_with_index_1 index = [] @e.each_with_index do |n, idx| index << idx end assert_equal index, [0, 1, 2] end def test_each_with_index_2 numbers = [] @e.each_with_index do |n, idx| numbers << n end assert_equal numbers, [1, 2, 3] end def test_each_with_index_3 assert_equal @e.each_with_index.class, Enumerator end end
テスト実行.
$ bundle exec ruby 08.rb Started with run options --seed 32833 GakushuTest test_each_with_index_1 PASS (0.00s) test_each_with_index_2 PASS (0.00s) test_each_with_index_3 PASS (0.00s) Finished in 0.00150s 3 tests, 3 assertions, 0 failures, 0 errors, 0 skips
ブロックを省略した場合には, Enumerator クラスのオブジェクトを返すことも確認.
以上
知らないメソッドだらけで楽しくなってきた.
フムフム.