マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

Ruby でもっとオレ的な if 関数を

前回の話でちょっと出した、残念な「メソッド的 if」について。

1.upto(20) do |n|
  (n % 15 == 0).if {
    puts 'FizzBuzz'
  }.else(n % 3 == 0).if {
    puts 'Fizz'
  }.else(n % 5 == 0).if {
    puts 'Buzz'
  }.else {
    puts n
  }
end

(真偽値).if {...} の形に合わせて else-if をメソッドチェーンの形に入れようとすると、上のような気持ちの悪い形にせざるを得なかった。この形は他にも問題があって、

  }.else (n % 3 == 0).if {

と空白文字を入れると構文解析が変わってエラーになる。それなんて Perl

それから、これは今まで挙げた全ての実装に当てはまることだが、else-if の条件式の扱いが実は正しくない。どこかの if/else-if の条件式が真になって対応する記述が実行されたら、その後にある else-if の条件式は評価されないはずである。

よく考えてみれば、「if メソッド」でなくて「then メソッド」ということにすればよい。

1.upto(20) do |n|
  (n % 15 == 0).then {
    puts 'FizzBuzz'
  }.elsif { n % 3 == 0 }.then {
    puts 'Fizz'
  }.elsif { n % 5 == 0 }.then {
    puts 'Buzz'
  }.else {
    puts n
  }
end

……ということを、偶然見かけた「ドリトル入門」のページ*1を読んで思いついた。

もはや「if 関数」を実装するという元ネタからは随分離れてしまっているので、これの実装は措いておきたい。というか、折角実装するのであれば、普通の if 文よりも高い機能を持たせるべきであろう……。

(続く)

*1:そこの 6.3 節の条件分岐の内部動作の解説。