ようへいの日々精進XP

よかろうもん

2018 年 06 月 20 日 (水)

ジョギング

  • お昼休みに自宅→香椎神宮香椎浜 で 35 分くらい
  • 引き続き, 右腰, 右臀部の強い張り (ストレッチでなんとかしている)
  • 引き続き, 左足足底筋にも違和感あり

日課

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

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

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

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

a = (1..5).partition(&:odd?)
p a

以下, 解答.

[[1, 3, 5], [2, 4]] が出力される

以下, irb による確認.

irb(main):024:0> (1..5).partition(&:odd?)
=> [[1, 3, 5], [2, 4]]

以下, 解説より抜粋.

  • Enumerable#partition はブロックの条件を満たす配列と条件を満たさない配列に分割して, 結合した2次元配列を返す
  • 条件を満たす配列は最初の要素に入る
  • Integer#odd? は self が奇数の場合に true を返すメソッド

Enumerable#partition をドキュメントより引用.

各要素を、ブロックの条件を満たす要素と満たさない要素に分割します。 各要素に対してブロックを評価して、その値が真であった要素の配列と、 偽であった要素の配列の 2 つを配列に入れて返します。 ブロックを省略した場合は、各要素に対しブロックを評価し、 上のようにその値が真であった要素の配列と、 偽であった要素の配列のペアを返すような Enumerator を 返します。

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

大文字, 小文字をざっくりと判別するメソッドを追加して, 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?)
['aA', 'az', 'Za', 'Bq', 'GG'].partition(&:islower?)
['aA', '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"]]
irb(main):010:0> ['aA', 'az', 'Za', 'Bq', 'GG'].partition(&:islower?)
=> [["az", "Za", "Bq"], ["aA", "GG"]]
irb(main):011:0> ['aA', 'az', 'Za', 'Bq', 'GG'].partition(&:isupper?)
=> [["aA", "GG"], ["az", "Za", "Bq"]]

Enumerable#partition と関係無いけど, 小文字と大文字が混在している場合には, 最後の文字が評価される.

Integer#odd? をドキュメントより引用.

自身が奇数であれば真を返します。 そうでない場合は偽を返します。

irb(main):002:0> 1.odd?
=> true
irb(main):003:0> 2.odd?
=> false

ちなみに, Integer#odd? に対して, Integer#even? も利用可能.

自身が偶数であれば真を返します。 そうでない場合は偽を返します。

irb(main):004:0> 2.even?
=> true
irb(main):005:0> 1.even?
=> false

例外

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

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

以下, 解説より抜粋.

  • :fish は Symbol クラスのオブジェクト
  • String#+ の引数は String クラスを期待する為, String クラス以外のオブジェクトが渡された場合は, TypeError が発生する
  • 例外を捕捉する為に rescue で, 例外を受け取った際の処理を記述する
  • エラーが発生しなかった場合の処理を行うには else を用いる
  • エラー発生有無に関わらず, 必ず実行する処理を行わせる為には ensure を用いる

フムフム.