From: Yukihiro Matsumoto Date: 2014-07-12T15:20:37+09:00 Subject: [ruby-list:49870] Re: Rubyへの要望(願望) まつもと ゆきひろです In message "Re: [ruby-list:49868] Rubyへの要望(願望)" on Sat, 12 Jul 2014 13:12:53 +0900, MASAKI Yuhsuke writes: |Ruby listの皆様、はじめまして、MASAKI Yuhsukeです。 | |個人的にRubyに欲しい機能、Rubyに欲しい振る舞いを述べさせてください。 |なお、ちゃんと把握しているのは1.8.6で、それ以降についてはNEWSは見ましたが、 |「既にそうなっているよ!」「既に議題に上って結論出てるよ!」ということがあるかもしれませんが、ご容赦ください。 |(そもそも誤解があるかもしれませんが、それもご容赦ください) | |なお、大いにIf you want Perl, you know where to find it.なところがあるかと思われますが、ご容赦くださいませ。 | |#inpicit Array#to_s |Array#to_sの挙動が変更された上、暗黙に文字列を要求するところでArrayを与えることが禁止されていますが、 |値が1以上で、内容文字列が操作されるようなケースにおいて、値はStringまたはArrayとなり、 |それが文字列を要求するメソッドに渡されるケースにおいてはArrayが自動的に連結されてStringとして振る舞うことが望ましいことは多々あります。 |そのようにしておくことにはやはり支障があるのでしょうか。 |なお、StringとIntegerの変換もできるだけinplicitにやって頂けると嬉しいのですが… Rubyの歴史の初期においては、Perlの影響もあって、今よりもより 積極的に暗黙の変換を許していましたが、挙動が期待と違った時の ダメージが大きい、バグの発見が遅れるなどの理由で現在のように なりました。.to_sを追加することでの対処をお願いしています。 |#3 part forとcontinueブロック |continueブロックはブロックにおいてbreakが呼ばれると実行されないループの付属ブロックです。 |現状、そのようにするためにはフラグ変数を用意してのensureか、もしくはnext/breakのかわりにthrowを使うようなことが必要で、スマートではあり |ません。 |例えば | |while re =~ str | # nextまたはbreakを伴うような条件判定のある内容 |continue | str.sub! matched_pattern, escape_str |end | |のようなことをしたいことがあります。 |また、3part forはこれに加えて、そのループで使うための値を用意することをループの中でもたせる、ということができます。 | |for(str = STDIN.gets nil; str == ptn1 .. ptn2; str = str.sub(re, substr)) | # strを使った処理... |end | |この場合、strはforループが終わったら殺してください。 continue節はPythonにあるものと同じものを期待してらっしゃるの でしょうか。面白いアイディアだと思って昔から考えているのです が、難点はRubyの場合、ループなどはブロックを使うことを推奨し ており、continue節の導入が正当に意味づけしづらいところです。 同様の理由で3 part forも賛成しにくいです。むしろもっとブロッ クを使って欲しいところです。 |#文字列の強制エンコーディング処理 |Web appなどでは入力文字のエンコーディングを強制することができないため、 |「自動判別の上、特定のエンコーディングに強制変換する」機能が欲しいと思っています。 |今はNKFを使っていますが、日本語でない場合も考えられますから。 |lvのような振る舞いをしてくれるといいかな。バイト列の文字セットなどに関しては、予め優先順位を設定できるようにするか、 |欲を言えばバイトシーケンスから推測してくれるといいな、と思います。 そういうのがあるといいですね。もうちょっと具体化するといいの ですが。 |#Zsh EXTENDED_GLOBのサポート |Dir.globで**をサポートするなら、ZshのEXTENDED_GLOBをフルサポートして欲しい! |ZshのEXTENDED_GLOBは非常に便利ですし、**だけならkshでも*(...)でできてしまいますし。 |Dirに組み込めないにしても、標準ライブラリにできませんか。 ZshのGlob全部はシェルでないRubyでは実現できなかったような記憶 があります。どこまで欲しいのか、もうちょっと具体的な提案があ ると採用しやすいかもしれません。 |#IO.mkfifoが欲しい |プラットフォームごとの差異を吸収してくれて、さらにブロックで削除まで面倒を見てくれるといいな、と思います。 mkfifoはすべてのプラットホームにあるわけじゃないですからねえ。 POSIXの範囲なら使えるgemがあればよいのかもしれません。 |#File#flockにブロックを |File#flockの仕様がRubyらしくないと思うのです。 |できることならFile.openにflockまで持たせられるようにしてほしいのですが、それができないにしてもせめて |File.open(path, "r") do |f| | f.flock(:EX) do | # ... | end |end |とできるようにしてほしいと思うのです。 flockはfileがcloseすると解放されるので、 File.open(path, "r") do |f| f.flock(File::LOCK_EX) # ... end で十分だと思うのですが。ブロック形式の方が便利なケースを思い つきませんが、もしあるということでしたら再提案してください。 |#自由な区切り文字による入力をメソッド定義に |%q(...)形式ですが、特にDSL的アプローチをしていると新しいリテラルが欲しくなることは多々あります。 |これを |def Kernel.perquote_q(str) | # ... |end |のようなメソッドで定義できるようにしてくれると嬉しいと思います。 このようなアイディアは以前にも提案されたことがありますが、マ クロと同様にプログラムの構文的な解釈が変化してしまうので、や めておこうと考えています。 |#メソッド名にsymbolを増強 |同じくDSL的アプローチにおいてsymbolを使ったメソッド名が欲しいことが多々あります。 |?と!は自由に使えるとはいえ、どのように振る舞うべきかは決まってしまっていますから、振る舞いが規定されていないpostfix symbolが欲しいのと、 |単純に前置することでprivateなinstance methodだと理解されるようなsymbolのメソッドが欲しいとも思います。 |つまり | arg |が |self. arg |と認識されるということですね。 ちょっと提案の意味がわかりにくいです。 「識別子に使える記号を増やして欲しい」という提案であれば、以 前にも頂いたことがありますが、正直なところ記号があんまり残っ てないです。それにプログラムの読みやすさに貢献しないことが明 らかなので、あまり積極的になりづらいですね。 「前置することでprivateなinstance methodだと理解されるような symbol」については考えたことがありますが、これも互換性を維持 したまま導入できる記号がなさそうです。以前「_」を前置したら自 動的にprivateという実験をしてみましたが、意外と_で始まるメソッ ド名を使っているライブラリが存在してて断念しました。 |#blockをbindingで評価できるようにして |Procのインスタンスメソッドでなく、Kernel.evalが文字列でなくブロックもとれるようになれば良いと思うのですが、 |特定のbindingで評価したいブロックを予め書いておきたいケースは多々ありますし。 |私が抱えている実際のケースとしては、 |DSL的アプローチにおいて、本文中のローカル変数を後ろでまとめて定義できるようにしたいのですが、 |そうなると文字列で書かせる必要があり、美しくないので気に入らないのです。 |#明らかにいらないオブジェクトを解放して |一時変数などで大量のオブジェクトが生成されるケースで、実験はしていませんが理屈上は一時的にメモリーを非常に食ってしまうように思われます。 |GCの改善によってフリーズタイムが減少しているとしても、メモリー使用量自体を増大させたくないケースは多々ありますから、 |リファレンスをひとつしか作らず、すぐに失うようなケース(メソッドで定義されたローカル変数がメソッド外に持ちだされないような)ではさっさと解放してほ |しいと思います。 |「使わないよ」と明示しないと難しいなら、何らかの特殊ブロックの中で作られたオブジェクトはブロックを終了すると直ちに解放される、ということではどう |でしょうか? |もっとインテリジェントには、メソッドやブロックのreturn時に局所的なGCを走らせるのが良いのではないかと思いますが、これは性能低下につながる気もし |ますね。 GCのことはGCに任せてください。今後ますます賢くなる予定です。 |#カンマ代替文字が欲しい |これもDSL的アプローチにおける話ですが、 |Ordered hash的な独自のクラスを定義した場合、その定義がどうしてもすべて,で区切らざるをえず、非常に見づらくなります。 |Perlでは=>が,のsynonymになっているため使い分けることで見やすくかけますが、やはりそういうものは欲しいな、と感じます。 |#Kernel.syscallにStringを渡せるようにしてほしい |まんまです。 「まんま」といわれてもちょっとわからないのですが、syscallでシ ステムコールの指定を番号ではなく文字列で指定したいということ でしょうか。 だとすると、気持ちはわからないでもないですし、それはそれなり に便利のような気がしないでもありませんが、そもそもsyscallを使 うことそのものが少ない上に使うのはプラットフォーム固有のマイ ナーなシステムコールを呼ぶ時とかでしょうから、これを支援する 価値があるかどうか疑問です。 |# next/redo/breakのターゲットを明示できるようにする |ネストしたループにおいてループ内でこの3つを全て使うようなケースでは、throw/catchとbegin/ensureを使ってもDRYを守れません。 ちょっとよくわかりませんでした。 |#File.openのargはinplicit to_sしてくれてもいいのでは |ファイルでスクリプタをとりますが、IO.openでなくFile.openでファイルデスクリプタをとる必要がありますでしょうか? to_pathを呼んでると思います。 |# String#evalが欲しい |文字列を式展開を含めた文字列解釈をするメソッドが欲しいのです。 実行時に式展開をするメソッドはprintf系で対応できると思います。 というか、実行時に式展開するのは意外と面倒です。 |# String#scanのブロック引数はMatchDataであるべきではないか? |影響の大きい変更となりますが… 今から変更するのは難しそうですね。残念ながら。 |# IO#write_reopen/IO#read_reopen? |IO.popenが全二重のパイプを作るので、リダイレクト面倒です。 |これに対する対応はないのでしょうか。IO.pipeとforkを使え、ということでしょうか。 open3? |# サブプロセスからの読み戻し |Kernel.`をKernel.execのような形で呼べる書式が欲しいということと、 |入力を渡してその出力が戻り値になるようなメソッドが欲しいと思います。つまり |filter(["wc", "-l"], "I\nwant\nit") |のようなものです。 aliasを使ってはどうでしょうか? 適切な名前があれば別名をあら かじめ用意するのもよいのかもしれません。 |# Enumerable#split |こんな感じ。 |class Enumerable | def split(obj) | result = [ Array.new ] | if block_given? | self.each {|i| yield(i) ? result[-1].push(i) : result.push(Array.new) } | else | self.each{|i| obj === i ? result[-1].push(i) : result.push(Array.new) } | end | end |end あってもいいかもしれませんね。 |# 先進的演算子 |他ではみないものですが、あるといいな、と思うのが |.= | obj .= method(arg) | -> obj = obj.method(arg) こういうのが欲しいのはわかりますが、この記法はあまりよくない ように思います。 |?= | obj ?= 1 : 0 #-> obj = obj ? 1: 0 | obj ?= + 1 : 0 #-> obj = obj ? obj + 1 : 0 |同様に&&=もメソッドをとれるようにしてもらえるといいな、と思っています。 あんまり嬉しさがピンと来ませんね。 obj ?= 1 : 0 と obj = obj ? 1 : 0 でそんなに良くなった気がしないのです。 |.& | メソッドを呼び出し、戻り値がnilならば続くメソッドを呼び出さずnilでreturnする。 | 特にl.gets.&chomp.splitというようなシーンでゆうようです。これは | ->() { (l.gets || break nil).chomp.split }.call | のようなメソッドです。中間オブジェクトを書かなくてすみ、すっきりしたコードが書けると思います。 Groovyの「?.」みたいなものでしょうか。あるといいなとは思って いるのですが、最適な記法が思いつかないでいます。「.&」は今ま でになかった提案ですが、これが最も良いかは自身がないです。 ActiveSupportではtryメソッドで似たようなことを実現してますね。 |# 軽量な起動, precompile |小さなスクリプトで頻繁に起動されるようなケースでは毎回Rubyを起動してparseしてcompileして、というのがかなりロスになります。 |PerlのC/CCコンパイラのように予め必要な情報を埋め込んだコードを生成しておくことはできないのでしょうか。 |もちろん、mrubyを使えばバイトコードまたはCコードにしておいてからの起動が可能でしょうが、CRubyでやりたいのです。 Emacsでもそうですが、最近マシンが高速化していてそういう対処 は不要になってきているようです。起動時間のかかるJRubyならと もかく、CRubyでそこまで必要なケースはかなり少なくなっている とおもうのですが、なにか事情があるのでしょうか。 まつもと ゆきひろ /:|)