ジョギング
日課
- (腕立て x 50 + 腹筋 x 50) x 3
蒸し暑くなってきた...
- 走った後とか辛い
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (13) ~
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 クラス, Enumerable クラス, String クラス, Object クラス
以下のプログラムを実行すると, ruby
が一文字ずつ表示される.
each_char
を置き換えても同じ結果になるメソッドを選択肢から選ぶ.
enum = 'ruby'.each_char p enum.next p enum.next p enum.next p enum.next
とりあえず, 上記を irb で試す.
irb(main):001:0> enum = 'ruby'.each_char => #<Enumerator: "ruby":each_char> irb(main):002:0> p enum.next "r" => "r" irb(main):003:0> p enum.next "u" => "u" irb(main):004:0> p enum.next "b" => "b" irb(main):005:0> p enum.next "y" => "y" irb(main):001:0> enum = 'ruby'.enum_for(:each_char) => #<Enumerator: "ruby":each_char> irb(main):002:0> p enum.next "r" => "r" irb(main):003:0> p enum.next "u" => "u" irb(main):004:0> p enum.next "b" => "b" irb(main):005:0> p enum.next "y" => "y"
ちなみに, String#next
や Integer#next
は, それぞれ succ
メソッドをエイリアスとして利用可能であるが, Enumerator#next
には succ
は存在しないので注意する.
ということで, 解答.
以下, irb で確認.
irb(main):006:0> enum = 'ruby'.to_enum(:each_char) => #<Enumerator: "ruby":each_char> irb(main):007:0> p enum.next "r" => "r" irb(main):008:0> p enum.next "u" => "u" irb(main):009:0> p enum.next "b" => "b" irb(main):010:0> p enum.next "y" => "y"
以下, 解説より抜粋.
each_char
にブロックを渡さない場合は,Enumerator
オブジェクトが作成されるEnumerator
オブジェクトを作成するには,enum_for
または,to_enum
を利用する- 引数にはレシーバーに送信したいメッセージ (メソッドの呼び出し) を定義する
- 引数を指定しない場合は,
each
がデフォルト値になる
次の例では、eachを使って1つずつアクセスして要素を表示しています。
irb(main):001:0> enum = [1, 2, 3, 4, 5].to_enum => #<Enumerator: [1, 2, 3, 4, 5]:each> irb(main):002:0> p enum.next 1 => 1 irb(main):003:0> p enum.next 2 => 2 irb(main):004:0> p enum.next 3 => 3 irb(main):005:0> p enum.next 4 => 4 irb(main):006:0> p enum.next 5 => 5 irb(main):001:0> enum = [1, 2, 3, 4, 5].enum_for(:reverse_each) => #<Enumerator: [1, 2, 3, 4, 5]:reverse_each> irb(main):002:0> p enum.next 5 => 5 irb(main):003:0> p enum.next 4 => 4 irb(main):004:0> p enum.next 3 => 3 irb(main):005:0> p enum.next 2 => 2 irb(main):006:0> p enum.next 1 => 1
例外
以下のコードを実行するとどうなるか.
begin print "foo" + :bar rescue TypeError print "TypeError." rescue print "Error." else print "Else." end
TypeError. が表示される
以下, irb による確認.
irb(main):001:0> begin irb(main):002:1* print "foo" + :bar irb(main):003:1> rescue TypeError irb(main):004:1> print "TypeError." irb(main):005:1> rescue irb(main):006:1> print "Error." irb(main):007:1> else irb(main):008:1* print "Else." irb(main):009:1> end TypeError.=> nil
以下, 解説より抜粋.
String#+
はString
クラスのオブジェクトを期待する- 引数に
Symbol
クラスを渡している為, 例外TypeError
が発生する else
ブロックは例外が発生しない場合に実行される
ちなみに, 以下のように書くとどうなるか.
begin print "foo" + :bar rescue TypeError print "TypeError." rescue print "Error." else print "Else." ensure print "Ensure." end
Type Error. と Ensure. が出力される
以下, irb による実行例.
irb(main):001:0> begin irb(main):002:1* print "foo" + :bar irb(main):003:1> rescue TypeError irb(main):004:1> print "TypeError." irb(main):005:1> rescue irb(main):006:1> print "Error." irb(main):007:1> else irb(main):008:1* print "Else." irb(main):009:1> ensure irb(main):010:1* print "Ensure." irb(main):011:1> end TypeError.Ensure.=> nil
ensure
ブロックは例外の発生関わらず, 必ず実行されるので, このコードにおいて例外が発生しない場合には, else 及び ensure ブロックまで含まれる出力となる.
irb(main):001:0> begin irb(main):002:1* print "foo" + 'bar' irb(main):003:1> rescue TypeError irb(main):004:1> print "TypeError." irb(main):005:1> rescue irb(main):006:1> print "Error." irb(main):007:1> else irb(main):008:1* print "Else." irb(main):009:1> ensure irb(main):010:1* print "Ensure." irb(main):011:1> end foobarElse.Ensure.=> nil
フムフム.