ジョギング
日課
- (腕立て x 50 + 腹筋 x 50) x 3
のんびりした休日
- お昼ごはん食べて, 気付いたら昼寝してしまっていた
- 夕飯食べて, ダラダラしてたら探偵ナイトスクープが始まって, 夫婦ふたりでお腹を抱えて笑った
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (16) ~
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)
Enumerable, Enumerator
次のプログラムを実行するために __(1)__ に適切なメソッドをすべて選ぶ.
class IPAddr include Enumerable def initialize(ip_addr) @ip_addr = ip_addr end def each return __(1)__ unless block_given? @ip_addr.split('.').each do |octet| yield octet end end end addr = IPAddr.new("192.10.20.30") enum = addr.each p enum.next # 192と表示される p enum.next # 10と表示される p enum.next # 20と表示される p enum.next # 30と表示される
to_enum enum_for
以下, irb による確認.
irb(main):001:0> class IPAddr irb(main):002:1> include Enumerable irb(main):003:1> irb(main):004:1* def initialize(ip_addr) irb(main):005:2> @ip_addr = ip_addr irb(main):006:2> end irb(main):007:1> irb(main):008:1* def each irb(main):009:2> return to_enum unless block_given? irb(main):010:2> irb(main):011:2* @ip_addr.split('.').each do |octet| irb(main):012:3* yield octet irb(main):013:3> end irb(main):014:2> end irb(main):015:1> end => :each irb(main):016:0> irb(main):017:0* addr = IPAddr.new("192.10.20.30") => #<IPAddr:0x00556232b19970 @ip_addr="192.10.20.30"> irb(main):018:0> enum = addr.each => #<Enumerator: #<IPAddr:0x00556232b19970 @ip_addr="192.10.20.30">:each> irb(main):019:0> p enum.next "192" => "192" irb(main):020:0> p enum.next "10" => "10" irb(main):021:0> p enum.next "20" => "20" irb(main):022:0> p enum.next "30" => "30" irb(main):001:0> class IPAddr irb(main):002:1> include Enumerable irb(main):003:1> irb(main):004:1* def initialize(ip_addr) irb(main):005:2> @ip_addr = ip_addr irb(main):006:2> end irb(main):007:1> irb(main):008:1* def each irb(main):009:2> return enum_for unless block_given? irb(main):010:2> irb(main):011:2* @ip_addr.split('.').each do |octet| irb(main):012:3* yield octet irb(main):013:3> end irb(main):014:2> end irb(main):015:1> end => :each irb(main):016:0> irb(main):017:0* addr = IPAddr.new("192.10.20.30") => #<IPAddr:0x0055a4d08957e0 @ip_addr="192.10.20.30"> irb(main):018:0> enum = addr.each => #<Enumerator: #<IPAddr:0x0055a4d08957e0 @ip_addr="192.10.20.30">:each> irb(main):019:0> p enum.next "192" => "192" irb(main):020:0> p enum.next "10" => "10" irb(main):021:0> p enum.next "20" => "20" irb(main):022:0> p enum.next "30" => "30"
以下, 解説より抜粋.
Enumerable
をインクルードした場合は,each
メソッドを実装する必要がある- ブロックが渡されない場合でも,
Enumerator
オブジェクトを返すようにして外部イテレータとしても使えるようにする Enumerator
オブジェクトを作成するメソッドはenum_for
, またはto_enum
を利用する
Integer#times
以下のコードを実行するとどうなるか.
10.times{|d| print d < 2...d > 5 ? "O" : "X" }
以下, irb で確認.
irb(main):021:0> 10.times{|d| print d < 2...d > 5 ? "O" : "X" } OOOOOOOXXX=> 10
ホー.
以下, 解説より抜粋.
Integer#times
は0
からself - 1
までの数値を順番にブロックに渡すメソッド- 設問では, ブロックに
0
から9
が渡される
以下は Integer#times
の利用例.
irb(main):001:0> 3.times { puts "Hello, World!" } Hello, World! Hello, World! Hello, World! => 3 irb(main):002:0> 0.times { puts "Hello, World!" } => 0 irb(main):003:0> 5.times {|n| print n } 01234=> 5
d < 2...d > 5
は, 条件式に範囲式の合わせ技
これは何だ...ということで, ドキュメントより引用.
条件式として範囲式が用いられた場合には、状態を持つ sed や awk 由来の 特殊な条件式として振る舞います。 「..」の場合: 1. 初期状態では式1だけを評価し、式1が真を返すまでは false を返します。 2. 式1が真を返すと true を返します。式2が真なら初期状態に戻ります。 3. この後は式2だけを評価し、式2が真を返すまで true を返します。 4. 式2が真を返すと true を返したあと、初期状態に戻ります。 「...」の場合: 1. 初期状態では式1だけを評価し、式1が真を返すまでは false を返します。 2. 式1が真を返すと true を返します。 3. この後は式2だけを評価し、式2が真を返すまで true を返します。 4. 式2が真を返すと true を返したあと、初期状態に戻ります。
以下, サンプル.
irb(main):001:0> 5.times{|n| irb(main):002:1* if (n==2)..(n==3) irb(main):003:2> p n irb(main):004:2> end irb(main):005:1> } 2 3 => 5 irb(main):006:0> 5.times{|n| irb(main):007:1* if (n==2)...(n==3) irb(main):008:2> p n irb(main):009:2> end irb(main):010:1> } 2 3 => 5 irb(main):011:0> 5.times{|n| irb(main):012:1* if (n==2)..(n==2) irb(main):013:2> p n irb(main):014:2> end irb(main):015:1> } 2 => 5 irb(main):016:0> 5.times{|n| irb(main):017:1* if (n==2)...(n==2) irb(main):018:2> p n irb(main):019:2> end irb(main):020:1> } 2 3 4 => 5
ムムム.