朝、ふと見ると、次女のほっぺたが膨らんでいる。あらら。
今日は結婚記念日(14年目)なので、なにかしようかと思ったが、 病人がいるのでは仕方がなくおとなしくしていることにする。
実家には妹が戻ってきているので、会いに行きたかったのだが、 おたふく風邪を蔓延させてもいかんしなあ。
たとえば
foo(x) if x = bar()
のようなコードではxへの代入がfoo(x)での参照よりも後ろに来ているので、 前のxはメソッド呼び出しとして解釈されてしまう。 [ruby-core:06684]では、上記のコードを
if x = bar() foo(x) end
と完全に同一にすることが提案されている。
が、正直あんまり乗り気じゃない。
ま、実装が面倒くさい(2パスかバックパッチングが必要になる)というのが最大の理由だが、 そのような面倒な処理を行って発生する違いというのは
くらいだから。それに結局
loop do p a a = 5 end
とか
if false a = 5 end p a
のようなコードで発生する「実際の代入処理の実行(動的)と代入文によるローカル変数の宣言(静的)」の問題がすべて解決するわけでない以上、あんまり嬉しくないのではないだろうか。
ここで、(どうせ2パスにするなら)もう一歩進めて、「そのメソッド内で代入の左辺に登場する識別子はどこでもローカル変数とみなす」というルールを導入することが考えられる。これなら、上にあげたloopやifのものにも対応できる。
しかし、このルールには、ある識別子がローカル変数かどうかメソッド全体を見ないとわからないので、 コードの理解しやすさが下がる危険性がある。メソッドが小さい時はいいけど、大きなメソッドがないとは限らないし。まあ、(かっこを省略した)無引数メソッド呼び出しと同名のローカル変数が共存するときにしか、問題にならないので、気にすることはないのかもしれないけど。
This work is licensed under a Creative Commons License.
モディファイア内での代入の件ですが、判断はお任せしますがリファレンスマニュアルに書いておいてください。現状は記述がないので、通常のifと同じだろうと想定して悩んだ覚えありです。
「通常のifと同じだろう」というのは興味深い反応ですね。<br><br>私としては現状が「通常と同じ」で、modifierの条件部での代入が前の式に影響を与えたら、そちらの方が特記すべき事項のように感じるのですが、それはあまりに実装よりの発想なのでしょうか。
文法解析のコンテキストと実行のコンテキストで解釈の順序が違うので、両者を混同して後者に引きずられると「同じであろう」となるのも分かる気がします。<br>x がメソッドなのか変数なのかという判定を、実際の実行段階まで遅延できれば解決しますが……
おっしゃる通り、実行時への遅延を行えば「この問題」は解決しますが、また別の問題を生みそうです。<br><br>その辺を見積もるのが難しいので躊躇しちゃうんですよねえ。
>modifierの条件部での代入が前の式に影響を与えたら<br><br>if修飾子の処理の流れを考えれば、<br> if 条件の処理 -> 左辺式の処理<br>ですから、if 条件の処理の副作用が残る(=if式と同じ)と考えるのは自然かと思います。<br>まあ、そもそもif修飾子の処理の流れが特殊なのですが……
ふと思ったのですが、まつもとさんは<br> class Proc<br> def if( var )<br> if (var) then self.call else nil end<br> end<br> end<br> Proc.new{ 実行部 }.if(条件式)<br><br>みたいなのを想定しているのですか?
コメントしっぱなしですいません。通りすがりの人や野分さんのおっしゃっ<br>てるような意味です。<br><br>>それはあまりに実装よりの発想なのでしょうか<br>無知には限りがないということで。(^^;;;<br><br>エラーになって初めていろいろと試し、同じコードがグローバル変数なら<br>うまくいくことを発見し、ローカル変数の記述を読んでようやく、事態を<br>だいたい理解しました。<br><br>マニュアルだけを頼りにプログラムを書いているユーザは、愚かにもこん<br>な試行錯誤を繰り返しながらプログラム組んでるわけです。その時間を節<br>約できるように、修飾子のところに注記を入れておいていただけると幸い<br>です。