マクロツイーター

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

Rubyでもっと自分好みの if 関数を

Ruby女子と高らかに宣言しておきながら好きな関数がifというのは解せぬ。Rubyistではない僕でもRubyにおいてifが関数ではなく制御構文であることは知っています。どういうことなのか。Rubyの話ではないということでしょうか。確かに「好きなRubyの関数」などとはどこにも書かれていません。

いやちょっと待て。LispHaskell だと大騒ぎ*1しなくても、Ruby なら手続きブロックがある*2から「if 文のように見える」条件分岐の関数は実装できるんじゃないか。Ruby 芸人ではない私でもそう思えてきて、どうせ既に誰かがネタ披露しているだろうと、ちょtっとググってみたら、コレが出てきた。

_if(x.zero?) {
  puts 'Zero!'
}.elsif(x == 1) {
  puts 'One!'
}.elsif(x == 2) {
  puts 'Two!'
}.else {
  puts "#{x}!"
}

……なるほど。

.else というのが多少強引だが、確かに「_if (条件) { ... } else { ... }」とか「_if (条件) { ... } { ... }」のように書けるようにするのは難しそうだ。「Ruby なんだから if 関数でなくて if メソッドだ!」ということで「(条件).if { ... }.else { ... }」のように書くことを考えたが、そうすると elsif が上手く書けなくなってとても残念なことになった。ので書式の設計については拘らないことにする。

だがしかし、「Rubyで_if関数」での実装に関しては私にとっては非常に気に入らない部分がある。何かというと

_if 関数の実装に既存の if 文を使っている

ことである。例えば、「Ruby で配列のソートを実装しなさい」という課題があったとして、

def sort(a) a.sort end

を書いて「できました!」と言ったら、頭の上に大きな金だらいが落ちてくることは避けられないだろう。実装することが目的であれば、既存のものとは独立に行うべきであることは当然である。*3というわけで、if 式を用いずに _if 関数を実装してみた。

見ての通り、iffunction.rb のソースの中に if 式は全く登場しない。勿論、三項演算子やその他の論理演算子*4も使っていないが、これで先述の _if 関数と同じものが実現できる。

えっ、大して面白くないって? うーむ、Ruby は難しいな……。

*1:関数のない言語は騒ぎに加わることすらできぬ…。

*2:つまり無名関数を書くのに lambda とか function とか書く必要がない。

*3:「待て、if を関数の形式にしたいのであって、誰も if の機能の実装を求めているわけじゃない」というツッコミについては、それを言うと話が終わってしまうので、是非とも遠慮しておこう。

*4:and と or があれば if と大体等価なことができることに注意。