ジョギング
日課
- (腕立て x 50 + 腹筋 x 50) x 3
奥さんと天神デート
天神で所用を済ませた後, ブラブラと博多まで夫婦で歩く. その途中で櫛田神社に立ち寄ってお参り.
初の櫛田神社だった.
博多駅の地下街にある焼肉屋さんで夕食. お腹一杯食べた.
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (10) ~
REx - Ruby Examination の問題を自分なりにアレンジした上で 1 〜 3 問くらいずつ解いていく. 正直言ってかなり難しい. 尚, irb に動作確認環境は以下の通り.
$ ruby --version ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux] $ irb --version irb 0.9.6(09/06/30)
Enumerator クラス
以下のプログラムの __(1)__ に適切なコードを入力して実行すると, [98, 97, 110, 97, 110, 97]
と表示される.
期待した結果を得られるように正しい選択肢を選ぶ.
enum_char = Enumerator.new do |yielder| "banana".each_char do |chr| __(1)__ end end array = enum_char.map do |chr| chr.ord end p array
yielder << chr
以下, irb による確認.
irb(main):001:0> enum_char = Enumerator.new do |yielder| irb(main):002:1* "banana".each_char do |chr| irb(main):003:2* yielder << chr irb(main):004:2> end irb(main):005:1> end => #<Enumerator: #<Enumerator::Generator:0x0056404d2ee058>:each> irb(main):006:0> irb(main):007:0* array = enum_char.map do |chr| irb(main):008:1* chr.ord irb(main):009:1> end => [98, 97, 110, 97, 110, 97] irb(main):010:0> irb(main):011:0* p array [98, 97, 110, 97, 110, 97] => [98, 97, 110, 97, 110, 97]
以下, 解説より抜粋.
- map メソッドのブロックは Enumerator オブジェクトをレシーバーとした場合に,
Enumerator::Yielder
オブジェクトとなり, 設問上のプログラムでは変数 yielder を指す Enumerator::Yielder
を評価するには,<<
を呼び出す
フムフム.
ちょっと理解に苦しんだので, コードを自分なり解析していくことにする.
- Enumerator クラスについて
ドキュメントより引用.
each 以外のメソッドにも Enumerable の機能を提供するためのラッパークラスです。
Enumerator.new することで, Enumerable なオブジェクトを生成することが出来るという理解. また, Enumerator を生成する場合,
を利用する.
- そして,
Enumerator.new
について
さらに, ドキュメントより引用.
Enumerator オブジェクトを生成して返します。与えられたブロックは Enumerator::Yielder オブジェクトを 引数として実行されます。 生成された Enumerator オブジェクトに対して each を呼ぶと、この生成時に指定されたブロックを 実行し、Yielder オブジェクトに対して << メソッドが呼ばれるたびに、 each に渡されたブロックが繰り返されます。 new に渡されたブロックが終了した時点で each の繰り返しが終わります。 このときのブロックの返り値が each の返り値となります。
以下, サンプルコード.
enum = Enumerator.new{|y| (1..10).each{|i| y << i if i % 5 == 0 } } enum.each{|i| p i }
上記のサンプルを irb で実行する.
irb(main):001:0> enum = Enumerator.new{|y| irb(main):002:1* (1..10).each{|i| irb(main):003:2* y << i if i % 5 == 0 irb(main):004:2> } irb(main):005:1> } => #<Enumerator: #<Enumerator::Generator:0x0055b00eac7a60>:each> irb(main):006:0> enum.each{|i| p i } 5 10 => 1..10
- 上記のサンプルだと,
y
が Enumerator::Yielder オブジェクトになる - Enumerator::Yielder オブジェクトに対して,
<<
を呼ぶと{|i| p i }
が実行される
という理解しか今のところは出来ない...
他にも Enumerator の実行例.
irb(main):003:0* enum = Enumerator.new(str, :scan, /\w+/) (irb):3: warning: Enumerator.new without a block is deprecated; use Object#to_enum => #<Enumerator: "Yet Another Ruby Hacker":scan(/\w+/)> irb(main):004:0> enum.each {|word| p word } "Yet" "Another" "Ruby" "Hacker" => "Yet Another Ruby Hacker" irb(main):005:0> str.scan(/\w+/) {|word| p word } "Yet" "Another" "Ruby" "Hacker" => "Yet Another Ruby Hacker" irb(main):006:0> "Hello, world!".scan(/\w+/) => ["Hello", "world"] irb(main):007:0> "Hello, world!".to_enum(:scan, /\w+/).to_a => ["Hello", "world"] irb(main):008:0> "Hello, world!".to_enum(:scan).each(/\w+/).to_a => ["Hello", "world"]
フムフム...