Ruby 初心者スレッド Part 17

このエントリーをはてなブックマークに追加
659デフォルトの名無しさん
質問というよりも言語仕様の問題に近いのかもしれませんが、
どうしてRubyにはインクリメントならびにデクリメント演算子がないのでしょうか?
実質 x += 1 で何も問題はないのですが、
この表記は個人的になんか気に入らないので、納得のいく理由が欲しいのです。
調べたりしてもなぜないのかまで踏み込んでいるところが見つからなくて……よろしくお願いします。

前置や後置でややこしいからかな……などと思いましたが、
それならば後置限定で採用するなりすればいいじゃないかと思うのは浅知恵でしょうか?

ならびに x.next x.succ で後置インクリメントじみた挙動が実現できるのは知っていますが、
インクリメントの意味合いでこのメソッドを使用するのは感心できる行為なんでしょうか?
またその場合、インクリメントはメソッド、デクリメントは演算子とアシンメトリになってしまうのですが、
なんかもう全部ひっくるめて、ここらへんはどう解釈すればいいんでしょうか?
660デフォルトの名無しさん:2008/02/08(金) 01:41:44
>>659
現行のRubyにインクリメント演算子が無いのは言語作成者のポリシー。
10年も前のMLでの発言だが、基本的には変わってないはずだ。
ttp://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/5323
> すんません.この件は以前から指摘されているのですが(演算子はC
> に似ているのに++と--は対応する演算子が無い),++の動作が本質
> 的に「変数を操作する」ものであるため,変数がオブジェクトでな
> いRubyでは導入できないでいます.++や--の「オブジェクト指向的
> 意味」がRubyの他の部分と整合性を保ったまま定義できれば採用し
> たいのですが….
うまい実装の仕方があれば要望として取り入れると思うぞ。
661デフォルトの名無しさん:2008/02/08(金) 01:47:56
あと

> x.next x.succ で後置インクリメントじみた挙動が実現できる
できないと思うぞ
i = i.succ
と書くことは
i += 1
と書くのと見栄え的にも手間的にもたいして変わらないんじゃないかと
662デフォルトの名無しさん:2008/02/08(金) 01:49:15
Cだとx++;で済んで簡潔なのかもしれんが、
例えばループ書くのに使うときとかは、ブロック使ってメソッドに抽象化して使う
ようにして、元が多少ダサくなるのは見逃してくれ。
663デフォルトの名無しさん:2008/02/08(金) 01:57:55
なんでインクリメント作れないのかは
「整数オブジェクトを破壊的に変更できないから」というのもあると思う
664デフォルトの名無しさん:2008/02/08(金) 02:11:45
俺もRuby使って最初に躓いたのが、++と--が使えないことだったw
Matzらしくもない。こんなんとっとと取り込んじまえばイイヤン。
665659:2008/02/08(金) 02:15:06
>>660-663
まとめてですみません。素早いお返事ありがとうございます。
確かにそう考えると合点がつきますね。
自分で考えても全然納得できなかったのですが、ようやくすっきりしました。
ありがとうございます。

>>661
できませんね……
succをリファレンスで調べたときに「インクリメントの代替はあるじゃん!」と勘違いして、
そのままずっと勘違いし続けてたみたいです。重ね重ねありがとうございます。
666デフォルトの名無しさん:2008/02/08(金) 02:18:50
>>660の「変数がオブジェクトでない」ってどういう意味?
667デフォルトの名無しさん:2008/02/08(金) 02:20:24
>>665
え〜納得しちゃうの?w

ごねようぜ・・・w
668デフォルトの名無しさん:2008/02/08(金) 02:35:19
>>667
「しんたっくすしゅがーとかでさいようしましょうよ〜」とかでいいですか?w
いや本当はちょっとごねたいんですけど、なにぶん『初心者スレッド』で質問している程度なんで
納得した先にできることがないっす。
+= とか本当は嫌いなんだけどなあ……みたいな感じで。
669デフォルトの名無しさん:2008/02/08(金) 02:41:47
>>668
かわいくゴネたら、俺がパッチ作って匿名でRubyメーリングリストに
なげるっていう条件でどう?w

かわいくなかったら、作らないw
670デフォルトの名無しさん:2008/02/08(金) 03:40:39
>>666
単なる名札。
671デフォルトの名無しさん:2008/02/08(金) 03:59:32
>>659-670
先日、io-languageスレで、++ を実装しようとしてこねくり回してたところだったんで、
タイムリーすぎて吹いた

なんでスマートにできないかというと、
メソッド内で、メソッドを呼んだオブジェクトを、格納した変数に代入できないから。

で、スマートな解決法はある。
Fixnum なら、Fixnum に 中身のデータを設定するメソッドを作ってやればいい。
例えば、Fixnum.set_value() みたいな。
ただし、Rubyのソースをいじるはめになるだろう

どーしても、Rubyのコードでやりたければ、Fixnumのメンバを持った、
Fixnumのラッパーを作るしかないだろうな。
そうすれば、簡単に実現できる。
結局、数字のリテラルを書くように使えず、そのクラスをいちいち new しないといけないのが面倒だが
672デフォルトの名無しさん:2008/02/08(金) 04:00:27
変なところで、句読点打った orz

> メソッド内で、メソッドを呼んだオブジェクトを、格納した変数に代入できないから。

メソッド内で、メソッドを呼んだオブジェクトを格納した変数に、オブジェクトを代入できないから。
673デフォルトの名無しさん:2008/02/08(金) 04:02:27
> 「整数オブジェクトを破壊的に変更できないから」というのもあると思う

ゲ、>>663 が簡潔にまとめてるじゃないか ・・・ orz
674デフォルトの名無しさん:2008/02/08(金) 05:28:31
>>660
残念ながら松本が++が嫌いだと言ってますので多分ないでしょう。
675デフォルトの名無しさん:2008/02/08(金) 06:12:21
a.++
で万事解決
676デフォルトの名無しさん:2008/02/08(金) 07:59:16
>>675
> a.++
> で万事解決

だーかーらー

Rubyの数関係のオブジェクトはイミュータブル、ってのがわかってないダロオマエ
677デフォルトの名無しさん:2008/02/08(金) 08:24:51
rubyのオブジェクト指向度の低さに唖然・・・
678デフォルトの名無しさん:2008/02/08(金) 08:48:36
smalltalkerが来ましたか
679デフォルトの名無しさん:2008/02/08(金) 09:05:54
Smallalk 使いから見ると Ruby はリフレクションが貧弱だよね。
これじゃ、まともなリファクタリングブラウザも作れないだろう…と。
680デフォルトの名無しさん:2008/02/08(金) 09:14:09
a.++!
でよくね
681デフォルトの名無しさん:2008/02/08(金) 09:36:37
a = 1
b = a
a.++!
p b
682デフォルトの名無しさん:2008/02/08(金) 10:24:56
Smalltalkから馬鹿にされるのはしかたないけど、C++から馬鹿にされると釈然としないかも。

683デフォルトの名無しさん:2008/02/08(金) 10:39:02
irb> n = 100
irb> p [n, 100, 99+1, 101-1, 99.succ, 'd'[0], '100'.to_i].map{|e| e.object_id}
[201, 201, 201, 201, 201, 201, 201]

Rubyでは、同じ整数値である限り、同じオブジェクト
684デフォルトの名無しさん:2008/02/08(金) 11:33:22
C++とか、
プリミティブ型があるJavaからも馬鹿にされたくはないな
685デフォルトの名無しさん:2008/02/08(金) 11:53:57
>>683
スゲー
686デフォルトの名無しさん:2008/02/08(金) 12:53:58
>>683
同じ整数値っていうかFixnumの場合だけじゃまいか
irb(main):002:0> [(2 ** 30).object_id, (2 ** 30).object_id]
=> [21803310, 21802580]
687デフォルトの名無しさん:2008/02/08(金) 12:59:06
>>679
>Smallalk 使いから見ると Ruby はリフレクションが貧弱だよね。
>これじゃ、まともなリファクタリングブラウザも作れないだろう…と。
SmallalkじゃなくてSmalltalkな。
それはいいとして、>>679にはぜひSmalltalkのよさを語ってほしいな。
Smalltalkの強力なリフレクション機能がどんなものか知りたい。
688デフォルトの名無しさん:2008/02/08(金) 13:22:15
>>687
たとえば(リファクタリングとは直接関係ないけど)、くだんの #++ とかの実装は、
Ruby の貧弱なイントロスペクションじゃ逆立ちしても無理…とかいう話?
689デフォルトの名無しさん:2008/02/08(金) 14:20:18
>>688
#++は>663,671,672,676,683。README.EXT(.ja)を参照。
誤解を恐れずに簡略すると実はFIXNUMだけオブジェクトじゃない。
オブジェクトじゃないから状態(値)を変更できない。
値の変更は変数に対する操作(代入)で代用。
690デフォルトの名無しさん:2008/02/08(金) 14:25:58
実装の問題は別として
>>681 の p b で 2 が出力されておk、という人は多くないと
思うわけだが。
691デフォルトの名無しさん:2008/02/08(金) 14:54:58
Hash#compare_by_identityって破壊的なのに!つけないんだな
これだからrails厨どもは
692デフォルトの名無しさん:2008/02/08(金) 14:57:01
>>689
Smalltalk も SmallInteger(Fuxnum 相当)は事情は同じだよ?
693デフォルトの名無しさん:2008/02/08(金) 16:26:09
>>687-692
SmallTalkスレで聞いてきたよ。

アラン・ケイも認めた!Ruby>>>>>Smalltalk
http://pc11.2ch.net/test/read.cgi/tech/1150106090/169-171

SmallTalkでも、破壊的に変更できない事情は同じで、
そこを強力なメッセージとリファクタリングの言語機能でカバー
力技だから、スマートでないと言われたらそうかもしれない。

Matzは嫌がりそうw
694デフォルトの名無しさん:2008/02/08(金) 16:27:46
x リファクタリング
o リフレクション

>>687-688にturareta
695デフォルトの名無しさん:2008/02/08(金) 16:47:16
>>693
だが Squeak Smalltalk を参考に作られた Rubinius ならきっとやってくれる!