ようへいの日々精進XP

よかろうもん

2018 年 06 月 30 日 (土)

ジョギング

  • お休み

日課

  • おやすみ

PyCon Kyushu 2018 Fukuoka

pycon-kyushu.connpass.com

に終日参加した.

slideship.com

この発表が一番印象に残ったというか, あー, 自分は Python 2 系と 3 系の書き方がごっちゃになってて, しかもググったコードをコピペしているだけなんだなと切なくなったのでもっと Python を勉強せねばと思った次第.

懇親会の二次会まで参加したけど, 懇親会のほとんどはデンマーク人やコロンビア人, スイス人の Pythonista 達と日本語で他愛もない話に花を咲かせた.

今日のるびぃ ~ REx - Ruby Examination にチャレンジ (42) ~

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

以下のプログラムを実行すると, apple が一文字ずつ表示される. each_char を置き換えても同じ結果になるメソッドを選択肢から選ぶ.

enum = "apple".each_char

p enum.next
p enum.next
p enum.next
p enum.next
p enum.next

以下, 解答.

# 解答 1
enum = "apple".enum_for(:each_char)
# 解答 2
enum = "apple".to_enum(:each_char)

以下, irb による確認.

# 解答 1
irb(main):001:0> enum = "apple".enum_for(:each_char)
=> #<Enumerator: "apple":each_char>
irb(main):002:0> enum.next
=> "a"
irb(main):003:0> enum.next
=> "p"
irb(main):004:0> enum.next
=> "p"
irb(main):005:0> enum.next
=> "l"
irb(main):006:0> enum.next
=> "e"
irb(main):007:0> enum.next

# 解答 2
irb(main):008:0> enum = "apple".to_enum(:each_char)
=> #<Enumerator: "apple":each_char>
irb(main):009:0> enum.next
=> "a"
irb(main):010:0> enum.next
=> "p"
irb(main):011:0> enum.next
=> "p"
irb(main):012:0> enum.next
=> "l"
irb(main):013:0> enum.next
=> "e"
  • each_char にブロックを渡さない場合は, Enumerator オブジェクトが作成される
  • Enumerator オブジェクトを作成するには, Object#enum_for または Object#to_enum を利用する
  • 引数にはレシーバーに送信したいメッセージ(メソッドの呼び出し)を設定する
  • 引数を指定しない場合は, each がデフォルト値となる

String#each_char について

レシーバー文字列の各文字列に対して, 繰り返し処理を行う.

irb(main):002:0> 'hello'.each_char {|s| p s.upcase }
"H"
"E"
"L"
"L"
"O"
=> "hello"

これを enum_forto_enum で表現する.

# enum_for
irb(main):004:0> enum = 'hello'.to_enum(:each_char)
=> #<Enumerator: "hello":each_char>
irb(main):006:0> enum.each do |s|
irb(main):007:1*   p s.upcase
irb(main):008:1> end
"H"
"E"
"L"
"L"
"O"
=> "hello"

# to_enum
irb(main):009:0> enum = 'hello'.enum_for(:each_char)
=> #<Enumerator: "hello":each_char>
irb(main):010:0> enum.each do |s|
irb(main):011:1*   p s.upcase
irb(main):012:1> end
"H"
"E"
"L"
"L"
"O"
=> "hello"

例外

以下のコードを実行するとどうなるか.

begin
  print "liberty" + :fish
rescue TypeError
  print "TypeError."
rescue
  print "Error."
else
  print "Else."
ensure
  print "Ensure."
end

以下, 解答.

TypeError.Ensure.

以下, irb にて確認.

irb(main):001:0> begin
irb(main):002:1*   print "liberty" + :fish
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

以下, 解説より抜粋.

  • String#+ の引数には String クラスのオブジェクトを期待する
  • 設問では引数に Symbol を渡している為, TypeError 例外が発生する
  • また, ensure は例外発生に関わらず評価される

フムフム.