- ベストアンサー
Rubyにインクリメンタル演算子がない理由は?
Rubyには他の言語でよくある++演算子がないようなのですが、 なぜないのでしょうか? 盛り込むのはそう難しくないと思うので、ないのはそれなりの思想があると思うのですが、どういう意図なのでしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
No.1の方のURLが端的なのですが、もう少し詳しく書いてみます。 Ruby での「数」は「数が格納された箱」ではなく「数」そのものです。 例えば String は「文字列が格納された箱」なので、<< の用な破壊的なメソッドを使い、foo = "0"; foo << "1"; p foo とすれば "01" と表示されます。また、foo = "0"; bar = foo; foo << "1"; p bar としても、bar は foo と同じ文字列が格納された箱を示しているので "01" が表示されます。この辺りは Array や Hash などの「何かを格納する箱のようなもの」でも同じですね。 さて、Ruby では Fixnum などが数字そのもののためこの様な破壊的な動作が出来ません。もし出来てしまうと、foo = 0; foo++ としたときに、そのスクリプト中にある全ての 0 が 1 になってしまいます。これは Symbol・true・false・nil なども同じです。 もう少し簡単に言えば、Ruby では数字や Symbole などはリテラルで表現した物はどこでも同じインスタンスが返る(irb で 0.__id__ や :foo.__id__ を何度実行しても同じ値が返ってきて、"foo".__id__ は実行する度に違う値が返ってくる事などで確認できます)ため、++ の様なメソッドが存在してしまうと、foo = 0; bar = 0; foo++; p [foo, bar] と書いたとき、foo と bar は先の String の例と同様、同じオブジェクトを指しているので、[1, 1] と表示されることになる、ということです。 専門的(?)に言えば、これらは Flayweight パターンを利用した immutable なオブジェクトなので破壊的変更が出来ません。 なお foo += 1 は、Ruby の内部で foo = foo + 1 と展開されて解釈されているので問題ありません。 シンタックスシュガーとして Numeric#++ というメソッドを作りませんか? という話は、何度か No.1 の方の URL 以外でも出ていたと思うのですが、Matz 氏は Ruby のそのような世界観から考えると、破壊的に見えるメソッドが Numeric などに実装されるのは、それがシンタックスシュガーといえどやはり整合性に欠け好ましくない、ということで退けていたと思います。 個人的には、Ruby は内部イテレータ関係が豊富で for 文を使うことはまずありませんし、1.9系や 1.8.7 などのバージョンではさらに Enumerator が実装され (10..35).each.with_index{|i, idx| ...} などと書けるようになり、foo += 1 と書く機会がほとんど無いので気になりませんね。C++ や C# などの言語で無いと腹が立つでしょうけど(笑) 以上でご理解いただけたでしょうか?
その他の回答 (1)
- singlecat
- ベストアンサー率33% (139/418)
↓ここに書かれていますね
お礼
ありがとうございます!参考になりました。 ただ、 『++の動作が本質的に「変数を操作する」ものであるため,変数がオブジェクトでないRubyでは導入できないでいます.』 がいまいちしっくり来きてません なんとなく bar += 1 ができるからと思って、ためしに class Fixnum def ++ self += 1 end end とかってできそうな気がするんですが、たしかにやってみるとエラーになっちゃいますね。 ともあれ、ありがとうございました。
お礼
詳しい解説ありがとうございます! スッキリしました。