質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1012閲覧

|| と = の優先順位について

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

2クリップ

投稿2017/07/20 16:18

ruby

1>> a = nil 2=> nil 3>> a || a = 1 4=> 1

rubyに関する質問です。
基本的には || 演算子の方が = 演算子よりも優先順位が高いようなのですが、なぜ、上のコードのように a || a = 1 には a || (a = 1) のように括弧をつけなくても良いのかが不思議です。
優先順位通りなら(a || a) = 1 から処理されてエラーが出ると想像していました。
この場合は特別なパターンなのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

古いRubyの疑似BNFがあるので見てみると。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fbnf.html

=記号は MLHS `=' MRHSARG: LHS `=' ARG で使われますが、左側a||a MHLSLHS で受理できないので、全体を代入式とする解析結果はでてこなくて、
a=1aLHS1ARGとするARGとして、a||a=1ARG `||' ARGと解釈するのでしょう。

構文解析器だけでは曖昧性を除去できなくて、なにかのルールが別に書かれているのかもしれませんが、いずれにせよa || a = 1(a || a) = 1とは解釈することができないからa || (a = 1)だと解析されているのだと思います。


確かに、a||a=1 という式は a||(a=1) と認識されています。

% cat t.rb a=nil a||a=1 % ruby --dump parsetree ./t.rb ########################################################### ## Do NOT use this node dump for any purpose other than ## ## debug and research. Compatibility is not guaranteed. ## ########################################################### # @ NODE_SCOPE (line: 2) # +- nd_tbl: :a # +- nd_args: # | (null node) # +- nd_body: # @ NODE_PRELUDE (line: 2) # +- nd_head: # | (null node) # +- nd_body: # | @ NODE_BLOCK (line: 1) # | +- nd_head: # | | @ NODE_DASGN_CURR (line: 1) # | | +- nd_vid: :a # | | +- nd_value: # | | @ NODE_NIL (line: 1) # | +- nd_next: # | @ NODE_BLOCK (line: 2) # | +- nd_head: # | | @ NODE_OR (line: 2) # | | +- nd_1st: # | | | @ NODE_DVAR (line: 2) # | | | +- nd_vid: :a # | | +- nd_2nd: # | | @ NODE_DASGN_CURR (line: 2) # | | +- nd_vid: :a # | | +- nd_value: # | | @ NODE_LIT (line: 2) # | | +- nd_lit: 1 # | +- nd_next: # | (null node) # +- nd_compile_option: false

投稿2017/07/21 04:27

quickquip

総合スコア11038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/21 05:28

スッキリしました。 構文解析の調べ方も知ることができて大変勉強になりました。 丁寧に教えて下さりありがとうございました。
退会済みユーザー

退会済みユーザー

2017/07/21 10:29

勉強になります。
guest

0

こちら(rubyの代入演算子 ||)のページの情報によれば
a || a = 1と書くとa ||= 1の自己代入とほぼ同じ振る舞いになるそうです。

参考にしたページ
演算子式
Ruby の自己代入 x ||= 1 の謎

投稿2017/07/20 17:31

編集2017/07/20 17:35
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/20 18:17

その記法はもちろん知っています。質問は演算子の優先順位が入れ替わっている点についてです。
退会済みユーザー

退会済みユーザー

2017/07/20 19:32 編集

先ほど挙げた「Ruby の自己代入 x ||= 1 の謎」というページに 「この文はx || (x = 1)と解釈されることになっている。」 と書いてあるのでそれを信じれば a || a = 1はa ||= 1であり、a || (a = 1)であるはずだと思うのですが。 (私は詳しくないので間違えている可能性が非常に高い。)
退会済みユーザー

退会済みユーザー

2017/07/21 01:29

そのページの説明だと全部、x || (x = 1)という括弧付きの表記が使われていて、x || x = 1という括弧無しの書き方には触れていない気がします。
退会済みユーザー

退会済みユーザー

2017/07/21 05:00 編集

x ||= 1がx || x = 1と同じ(ような)振る舞いをするのならX || x = 1はx ||= 1と同じように解釈されているのではということです。つまりa || a = 1はa || (a = 1)として解釈されている、なぜなら a || a = 1はa ||= 1と(ほぼ)同じ意味だから。
退会済みユーザー

退会済みユーザー

2017/07/21 10:33

私のこねくり回した話は完全に間違いでした。 私はa || a = 1がa ||= 1と同じ解釈がされるように 予め設計されていると考えていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問