« Rubyを使ってみて | トップページ | SmartVisionセットアップ手順 »

unless... と if not...

またRubyネタになってしまうのですが、今僕がRubyに関して悩んでいることの一つに、unless... を使うべきか、if not... を使うべきか、というのがあります。

unlessというのはRubyの予約語で、

unless A
 B
end
は、
if !( A )
 B
end
と同じ意味を持ちます。Cだと、
if !( A ) {
 B
}
ですね。 つまり、Rubyにはifと逆の意味を持つ構文が用意されているのですが、これに関して、Rubyist Magazine 第10号のあなたの Ruby コードを添削します 【第 1 回】 pukipa.rbでは、以下のように書かれています。
C や Java から Ruby 移行してきた人にありがちなのが、C/Java にもある構文ばかり使って Ruby 特有の構文を避けることです。特に unless, until はなぜか嫌われているようです。
(中略...)
ではなぜ if not よりも unless が、while not よりも until がよいのでしょうか。その理由は、文を構成する要素数が減るからです。わたしが「if not A」という式を見る場合、まず if を見て、A を見て、それを not で反転します。つまり脳内操作は三つです。しかし「unless A」の場合、unless を見て A を見れば終わりなので二つです。
僕もまさしく「C や Java から Ruby 移行してきた人」なので、unlessに対して微妙に違和感があります。なんだかunlessを見ると、「なんだっけ?」って感じで一瞬思考停止してしまうんですよね。

もちろん、if !(...)という括弧が必要な書き方は美しくないことはわかっているので、unlessを使うようにしたいという気持ちもあるのですが、悩ましいことにRubyにはif not...という逃げ道があるのです。
notというのは、!と同様に単項演算子で、真偽をひっくり返す効果があります。ただ、全く同じではなくて、Rubyの演算子式の仕様を見ていただくとわかるのですが、!よりも優先順位が低いんですね。notの下は、andとorしかありません。つまり、「andとorを使わない」というコーディングルールを使っている限りは、if not...はunless...と同じ意味になるわけです。(andは&&の優先度が低いもので、notと!の関係と同様です。)

もちろん、他の人がコードを読む場合、戸惑うことは予測できます。つまり、

if not A && B
 C
end
というコードを見た場合、notが「A」にかかるのか、それとも「A && B」にかかるのかを理解するには、Rubyの演算子の結合順位を正しく理解していなければいけません。最悪勘違いする場合もあります。他方
unless A && B
 C
end
なら、たとえunlessで引っかかっても、勘違いすることはないですよね。そういう意味では、unlessの方が優れていますね。なんだか書いてるうちに、unlessの方が明らかに良い気がしてきました(^^;

あと、調べているうちに見つけたのは、英語的に言うとunlessとif notは意味が違うということです。つまり、unlessは唯一除外する条件を示すのに大して、if notは他にも条件がありうることを意味しているんですね。Rubyでの使われ方では、unlessの方が正しいような気がします。

というわけで、何だか拍子抜けな結果になってしまいましたが、これからはunlessを積極的に使っていくことにしようと思います(^^;

|

« Rubyを使ってみて | トップページ | SmartVisionセットアップ手順 »

「パソコン・インターネット」カテゴリの記事

コメント

いやいや、if notで十分だとおもうけどなー。ここは逆に予約語を増やすリスクを避けるべきだと思うんだけどなー。

そういえば、C++でおもしろい話が。C++の設計者のBjarne Stroustrup(なんて読むんだw)がusingとnamespaceを導入したとき、いかに他の人が使ってない言葉でわかりやすい予約語を導入するかを考えた末、1ヶ月間ベル研のコンパイラで勝手にusingとnamespaceを予約語にして誰も気づかなかったから予約語として採用したらしいよ。予約語を増やさない努力に関しては結構「C++の設計と進化」で語っていました。

投稿: がめら | 2005.12.25 02:16

うーん、そこがC++とRubyの思想の違いということなんじゃないかな。
RubyがPerlの「There's More Than One Way To Do It」的な考え方を受け継いでいるということもあると思うんだけど。
あと、標準ライブラリにも過剰なくらいメソッドが揃っていて、リファレンスマニュアルがないと人のソースは絶対読めないです。
この辺りが好き嫌いになってくるのかなあ。

投稿: ashel | 2005.12.25 02:31

ていうか、文章増えてるー。

if not A && Bなんて書いた時点でA && Bの部分は括弧で囲むでしょ。まぁ、といいつつunlessあったら俺もunless使う気がしてきた。

投稿: がめら | 2005.12.25 04:17

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/1789/7815351

この記事へのトラックバック一覧です: unless... と if not...:

« Rubyを使ってみて | トップページ | SmartVisionセットアップ手順 »