Ruby on Rails - Ruby Operator Priority - Brackets

The following code results in an error

Example 1

if params[:id] == '2' || params.has_key? :id abort('params id = 2 or nothing') end syntax error, unexpected tSYMBEG, expecting keyword_then or ';' or '\n' if params[:id] == '2' || params.has_key? :id 

However, switching conditional statements || adding brackets works 100%.

Example 2

 if params.has_key? :id || params[:id] == '2' abort('params id = 2 or nothing') end 

Example 3

 if (params[:id] == '2') || (params.has_key? :id) abort('params id = 2 or nothing') end 

Can someone explain to me why example 1 will lead to an error?

thanks

+2
source share
4 answers

Your problem occurs at:

 params[:id] == '2' || params.has_key? :id 

which can be simplified to:

 :foo || some_method :bar 

which causes the same error. This expression is in principle ambiguous between

 (:foo || some_method) :bar (1) 

and

 :foo || (some_method :bar) (2) 

When an expression is ambiguous, it is resolved by other factors. One of the factors, the priority of the operator does not say anything about the ambiguity between (1) and (2). The next factor is the linear order. Since || appears before the application () argument (omitted) in the expression in question, the former is applied before the latter. Therefore, the expression is interpreted as (1). Since (:foo || some_method) then parsed as an expression, there will be two expressions next to it. This is not grammatical, just like:

 :baz :bar 

is non-grammatical.

In fact, if you change the order as follows:

 some_method :bar || :foo 

then it will be interpreted as

 (some_method :bar) || :foo 

for the same reason, and the syntax error will disappear.

Also, when you resolve ambiguity, explicitly using parentheses to indicate the application of the argument:

 :foo || some_method(:bar) 

then there is no ambiguity to be resolved, and the syntax error disappears.

+4
source

Your :id is a symbol in Ruby.

 a = {'id' => 'a', 'value' => 'value'} a.has_key? 'id' => true a.has_key? :id => false 

So you need to change your code:

 if params[:id] == '2' or params.has_key? 'id' abort('params id = 2 or nothing') end 

Note. If you intend to use this code to verify a key before checking the value makes sense.

Note # 2: Tested with

 params = {'id' => 'a', 'value' => 'value'} if params[:id] == '2' or params.has_key? 'id' abort('params id = 2 or nothing') end 

and Ruby 2.0.0

Also check out this question for more information on Ruby characters.

+1
source

This is due to how Ruby evaluates the if .

Example 1 is similar if (params[:id] == '2' || params.has_key?) :id

which resolves an unexpected character error, as you can see syntax error, unexpected tSYMBEG .

0
source

As the guy says ... the parser does not assume that the character is a parameter for has_key? Method

You can get around the error by explicitly encoding parentheses

 if params[:id] == '2' || params.has_key?(:id) 
0
source

Source: https://habr.com/ru/post/1200269/


All Articles