ようへいの日々精進XP

よかろうもん

2018 年 06 月 01 日 (金)

ジョギング

日課

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

もりす

  • 久しぶりに串かつもりす
  • カレーが美味しかった

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

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)

alias

期待した出力結果になるように __(1)__ に適切なコードを選ぶ.

# コード
class String
  __(1)__ 
end

p "abcde".foo

# 出力結果
edcba

alias foo reverse alias :foo :reverse

以下, irb にて確認.

irb(main):001:0> class String
irb(main):002:1>   alias foo reverse
irb(main):003:1> end
=> nil
irb(main):004:0> 
irb(main):005:0* p "abcde".foo
"edcba"
=> "edcba"
irb(main):001:0> class String
irb(main):002:1>   alias :foo :reverse
irb(main):003:1> end
=> nil
irb(main):004:0> 
irb(main):005:0* p "abcde".foo
"edcba"
=> "edcba"

以下, 解説より抜粋.

  • alias 式はメソッドやグローバル変数に別名を付けることが出来る
  • 定義は以下のように, alias 新しい名前, 元になる名前 で, メソッドの場合にはリテラルかシンボルで指定する
alias new_method old_method
alias :new_method :old_method
alias $new_global_variable $old_global_variable

alias と同様の機能を持つ alias_method について, alias とは以下のような違いがある.

  • メソッド名は String または Symbol で指定する
  • グローバル変数の別名をつけることは出来ない
  • alias_method 自身はメソッドである為, オーバーライトが出来る
irb(main):001:0> class String
irb(main):002:1>   alias foo reverse
irb(main):003:1> end
=> nil
irb(main):004:0> 
irb(main):005:0* p "abcde".foo
"edcba"
=> "edcba"
irb(main):006:0> class String
irb(main):007:1>   alias_method "bar", "reverse"
irb(main):008:1> end
=> String
irb(main):009:0> 
irb(main):010:0* p "abcde".bar
"edcba"
=> "edcba"

alias キーワードと, alias_method メソッドの違いについては, 以下の記事が参考になった.

以下の部分.

This is because alias is a keyword and it is lexically scoped. It means it treats self as the value of self at the time the source code was read . In contrast alias_method treats self as the value determined at the run time.

フムー.

文法 (演算子)

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

v1 = 1 / 2 == 0
v2 = !!v1 or raise RuntimeError
puts v2 and false

true

以下, irb にて確認.

irb(main):011:0> v1 = 1 / 2 == 0
=> true
irb(main):012:0> v2 = !!v1 or raise RuntimeError
=> true
irb(main):013:0> puts v2 and false
true
=> nil

ホエー.

以下, 解説より抜粋.

  • 1 行目において, Fixnum クラス同士の除算は Fixnum クラスとなり, 0 == 0 が評価され, v1 は true となる
  • 2 行目では, or は左辺が真であればその結果を返す為, 左辺は評価されない (左辺が偽であれば, 右辺を評価する)
  • !!v1 は true となる, ちなみに !v1 は false となり, !!!v1 も false になる
  • また, or は評価する優先順位の低い演算子なので, v2 には !!v1 の結果である true が入る
  • 3 行目では, and は左辺が真であれば, 右辺の結果を返し, 左辺が偽であれば, 左辺の結果を返すが, and は評価の優先順位が低い為, puts v2 が評価される

以下, メモ.

irb(main):026:0> 1 / 2
=> 0
irb(main):027:0> 1 / 2 == 0
=> true
irb(main):028:0> !!true
=> true
irb(main):029:0> !!!true or raise RuntimeError
RuntimeError: RuntimeError
irb(main):030:0> true and false
=> false
irb(main):031:0> p true and false
true
=> false

フムフム.