[#48683] klass と Marshal.load(Marshal.dump klass) が同じにならない — dezawa <dezawa@...>
出沢です
5 messages
2012/04/06
[#48689] 日時の文字列をTimeクラスに変換したい — ichirojiro@...
ichirojiroです
7 messages
2012/04/09
[#48710] 多言語を含むUTF-8テキストから文字種を判定する方法 — えだ ゆきひこ <eda@...>
えだです。
7 messages
2012/04/25
[#48711] Re: 多言語を含むUTF-8テキストから文字種を判定する方法
— "NARUSE, Yui" <naruse@...>
2012/04/25
2012年4月25日11:19 えだ ゆきひこ <eda@nerv.org>:
[ruby-list:48703] 単項演算子 - に関する違和感
From:
小田 利通 <oda@...>
Date:
2012-04-20 07:31:04 UTC
List:
ruby-list #48703
小田と申します。
動作としては正しいのだけれど、なんとなく違和感があるコードの例を
2個あげます。
バグを作らない書き方などがあれば教えてください。
[1]
$ irb
irb> 0-30%360 ## - は2項演算子
=> -30
irb> -30%360 ## - は単項演算子で %(剰余)より優先順位が高い
=> 330 ## (-30)%360と同じ
irb> -1**2 ## - は単項演算子。でも **(累乗)の方が優先順位が高い
=> -1 ## -(1**2) と同じ
irb> (-1)**2
=> 1
一部の演算子の優先順位を並べると
高い +(単項) ! ~
** <---ここ **
-(単項) <---ここ -
* / % <---ここ %
低い + -
違和感を感じた理由は
-A+B は (-A)+B と同じで -(A+B) が違うことはすぐにわかる。
-A*B は (-A)*B と同じで -(A*B) と計算結果は同じになる。
-A%B は (-A)%B と同じだが -(A%B) と計算結果が同じになると期待してしまう。
なぜなら %(剰余)はなんとなく、加算(+)より、乗算(*)に近いと思っていて、
0-A*B と -A*B が同じなのだから、0-A%B も -A%B と同じだと思ってしまうから。
関係をまとめると次のよう(次はスクリプトではない)。
-A+B == (-A)+B == 0-A+B != -(A+B)
-A*B == (-A)*B == 0-A*B == -(A+B)
-A%B == (-A)%B != 0-A%B == -(A%B)
[2]
a.ceil より1小さい値と、a.floor より1大きい値を使おうと思いました。
b = a.ceil -1
c = a.floor+1
上のコードは、次のコードと同じで思ったようには動きません。
b = a.ceil(-1) # エラー
c = a.floor()+1
b で c と同じような計算をしようと思うと、次のコードです。
b = a.ceil - 1 または
b = a.ceil-1
マイナス - の前後の空白が2個と0個のときは同じ動作になり、
1個のときは別の動作になることが違和感の感じる理由です。
上のエラーの部分で ceil の代わりに1個の引数を許すメソッドならば
バグ取りがたいへんです。
[1] 、[2] どちらも、単項演算子 - に関わることです。
単項演算子の結果をそのまま(=括弧で囲わず)に
a) 2項演算子の項として使う 例) -30%360
b) 1項演算子の項として使う 例)--30
c) 括弧を省略したメソッド引数として使う 例) a.ceil -1
という動作は、いずれも違和感がありますが、
文法面では正しく、間違えて書いたときはバグが見つかりにくいです。
コードの作法みたいなもので解決できれば良いのですが、
空白を省いて短く書きたい場合や a.ceil, a.floor のように桁を揃えたい
ときもあると思います。
a),b),c) の場合にインタープリタがワーニングを出したり、
スクリプトの中に a),b),c) のコードがあるかどうかチェックするプログラムが
あればそれは便利だと思うのですが、どうでしょうか?
よろしくお願いします。