ようへいの日々精進XP

よかろうもん

2018 年 05 月 22 日(火)

ジョギング

日課

  • (腕立て x 50 + 腹筋 x 50) x 3

夕飯

  • 奥さんが作った「小松菜とお揚げの炊いたん」が美味しかった

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

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#partition

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

(1..5).partition {|n| n.odd? }
p a

[[1, 3, 5], [2, 4]]

以下, irb による実行例.

irb(main):004:0> (1..5).partition {|n| n.odd? }
=> [[1, 3, 5], [2, 4]]
# 以下と同義
irb(main):005:0> (1..5).partition(&:odd?)
=> [[1, 3, 5], [2, 4]]

以下, 解説より抜粋.

  • 各要素をブロックの条件を満たす要素と満たさない要素に分割する
  • 各要素に対してブロックを評価して, その値が真であった要素の配列と, 偽であった要素の配列の 2 つを配列に入れて返す
  • 設問では, Integer#odd? は self が奇数となる場合に true を返すので, 奇数配列と偶数配列が結合された配列を返す

もう少し確認.

Enumerable#partition はブロックの条件を満たす要素と満たさない要素を分割して返す.

irb(main):006:0> (1..10).partition {|n| n % 2 == 0}
=> [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]

ちょっと遊んでみる. 大文字, 小文字をざっくりと判別するメソッドを追加して, Enumerable#partition してみる.

# 大文字小文字を判別するメソッドを String クラスに追加する
class String
  def islower?
    self =~ /[a-z]$/ ? true : false
  end
  
  def isupper?
    self =~ /[A-Z]$/ ? true : false
  end
end
['A', 'Az', 'Za', 'Bq', 'GG'].partition(&:islower?)
['A', 'Az', 'Za', 'Bq', 'GG'].partition(&:isupper?)

以下, irb での実行例.

irb(main):015:0> ['A', 'Az', 'Za', 'Bq', 'GG'].partition(&:islower?)
=> [["Az", "Za", "Bq"], ["A", "GG"]]
irb(main):016:0> ['A', 'Az', 'Za', 'Bq', 'GG'].partition(&:isupper?)
=> [["A", "GG"], ["Az", "Za", "Bq"]]

Integer#odd は self が奇数であれば true を返す. 対して, Integer#even は self が偶数である場合, true を返す.

irb(main):017:0> 1.odd?
=> true
irb(main):018:0> 2.odd?
=> false
irb(main):019:0> 2.even?
=> true
irb(main):020:0> 100.even?
=> true
irb(main):021:0> 101.even?
=> false

例外

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

begin
  10/0
rescue ZeroDivisionError
  print "ZeroDivisionError."
rescue
  print "Error."
else
  print "Else."
ensure
  print "Ensure."
end

ZeroDivisionError.Ensure.

以下, irb による実行例.

irb(main):001:0> begin
irb(main):002:1*   10/0
irb(main):003:1> rescue ZeroDivisionError
irb(main):004:1>   print "ZeroDivisionError."
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
ZeroDivisionError.Ensure.=> nil

以下, 解説より抜粋.

  • ZeroDivisionError は整数に対して整数の 0 で除算を行ったときに発生する
  • エラーを受け取るためにはrescueで、例外を受け取った際の処理を記述する
  • エラーが発生しなかった場合の処理を行うには else を用いる
  • エラー発生有無に関わらず, 必ず実行される, 後処理を行うには ensure を用いる

フムフム.