[ruby-list:50743] Re: 割り算と正規表現リテラル
From:
OOTANI TAKASHI <tksotn@...117.cx>
Date:
2019-01-24 16:23:17 UTC
List:
ruby-list #50743
大谷です。
ありがとうございます。
仕様だろうけど、どういうときに演算子とみなされるんだろうと思っていました。
前後に空白を入れるか、入れないかを同じにすれば良かったんですね。
ファイルにプログラムを書くときは大丈夫でしょうけど、
irbやpryだと、つい空白が入ったり入らなかったり。
> 2番目の例の場合、本来は、そう解釈されなくてはならないとは必ずしも限らなくて、
については、演算子の結合の方が引数の結合より強いので、
> 「p(foo)/10」のように解釈される可能性はありそうなものですが、
は、無いかなと思ってましたが、そういう記述はリファレンスには無いですね。
ふとやってみた、
p foo && 5
p foo and 5
については予想通りの結果でした。andの結合は弱い。
リファレンスに記述のある { } と do end の関係と同じですね。
From: "Masa Sakano" <imagine@sakano.co.uk>
Subject: [ruby-list:50742] Re: 割り算と正規表現リテラル
Date: Thu, 24 Jan 2019 13:18:15 +0000
> 坂野正明です。
>
> これは、パースの問題ですね。
> 「/」は、Rubyデフォルトの有名どころで、除算、整除、正規表現の開始および終了、という
> 少なくとも4つの演算子の意味があります。加えて、ユーザーが(再)定義可能です。
> 正規表現の開始演算子、と解釈された場合、文は、そのあとの複数行にまたがることが許されます。
>
> p foo /10
>
> の場合、これは、
>
> p(foo/10) #
> 「foo÷10」の返り値を表示して、p()の結果を返す
> p(foo)/10 # 「foo」の返り値を表示して、「p(foo)」÷10
> の結果を返す
> p(foo /10 #
> 正規表現の後ろ側をプログラム最後まで探す →
> 存在しないので、エラー
> p(foo) /10 #
> 正規表現の後ろ側がプログラム最後まで探す →
> 存在しないので、エラー
>
> の4つの可能性があり得ます。
> 加えれば、それぞれに、foo
> がインスタンス変数かメソッドかの二つの可能性があります。
> (いずれも、それ以前の文のパースから、"p"が文の始まりである、と判断された時、という条件のもと。)
>
> Ruby
> のパースは恐ろしく賢くて、一番それらしいものを賢く選ぶことが普通ですが、
> それでも元の文があまりに不明瞭だと、エラーや警告が出ます。
>
> (多くの人間の期待と一致するだろう)例として、
>
> p foo/10 # => p(foo/10) と解釈
> p foo / 10 # => p(foo/10) と解釈
>
> のように解釈されます。
> ここで、特に
> 2番目の例の場合、本来は、そう解釈されなくてはならないとは必ずしも限らなくて、
> 「p(foo)/10」のように解釈される可能性はありそうなものですが、
> Ruby(少なくともRuby2)のパースはそれを避けているようです。
>
> なお、"foo"の部分がリテラルの数字の場合に限っては、数字に続く「/」は、前後の空白のある無しに関わらず
> 除算(または整除)記号とパーサーは解釈するようですね。だから、
> p 50 /10
> は、「p(50/10)」と解釈されるようです。
>
> ご投稿のケースでは、Rubyのパーサーが賢すぎて、パースの原則が一貫してないように見えたのが、
> 混乱を呼んだ一因でしょうか。
>
> 結論として、ご質問に一言で答えるならば、それは「Rubyの現在の仕様」と言ってよいでしょう。
>
>
> Rubyコードを書く時には、紛らわしい書き方はなるべく避けるべきなのが鉄則だと理解しています。
> でないと、Rubyのパーサーの判断と、プログラマーの判断が異なることはあり得ます!
>
> 具体的には、p()
> 文の場合、表示させる内容には、一切空白を入れずに書くのが原則だと理解しています。
> 例: 「p foo/10」
>
> 空白を入れたい場合は、「p(foo /
> 10)」のように、陽に括弧を入れるべきです。
> そうすると、紛れがありませんから。
>
> ご参考までに。
>
> 坂野正明
>
> On 24 Jan 2019, at 12:33, OOTANI TAKASHI wrote:
>
> > 大谷ともうします。
> >
> > def foo
> > 100
> > end
> >
> > p foo
> > p foo /10
> >
> > が、/
> > の後に空白を置かないと、もしくは、foo()にしないと、
> > unterminated regexp meets end of file のエラーになるのは、
> > 仕様でしょうか?バグでしょうか?
> > メソッドの引数とみなされてしまうようですね。
> >
> > エラーにならないケースだと、
> >
> > def foo(arg=nil)
> > 100
> > end
> > i=10
> >
> > p foo
> > p foo /10
> > p foo /i
> >
> > とか。
> >
> > --
> > tksotn
--
tksotn