Writing multiline arithmetic in Ruby

How to write multiline arithmetic in Ruby? I used to try something like y , then I realized that something was wrong with this code. I need to write multi-line arithmetic due to my very long equation.

 a = 5 b = 5 x = (a + b) / 2 puts x # 5, as expected y = ( a + b ) / 2 puts y # 2, what happened? 
+6
source share
3 answers

The Ruby analyzer will assume that the statement completed if it looks like it ended at the end of the line.

What you can do is leave the arithmetic operator immediately before the new line, for example:

 a = 1 b = 2 c = a + b 

And you get the expected result.

+5
source
 ( expr1 expr2 ) 

in fact, in Ruby, just like

 (expr1; expr2) 

which simply executes the first expression (for side effects) and returns the second (also after evaluating it)

+2
source

Try to think about the “expectations” of the interpreter and remember that in ruby, EVERYTHING is an expression (this means that everything evaluates some value, even constructs that are considered “special” in other languages, for example if-then-elses, loop, etcettera).

So:

 y = ( #1 a #2 + b #3 ) / #4 2 #5 

In line 1, we begin the declaration of the variable, and the line ends with an open (pending) bracket. The interpreter expects the rest of the definition, so it moves to the next line, looking for VALUE to assign var y .

On line 2, the interpreter finds the variable a , but does not contain parentheses. It evaluates a , which has a value of 5 , and since line 2 is a valid expression, the interpreter understands that this expression is finished (because in Ruby, the new OFTEN line means the indicator of the end of the expression). Thus, until now it has produced the value 5 , but its only expectation is that it must match the parenthesis.

If after that the interpreter found the enclosing parenthesis, it would assign the value a (ie 5) expression in the brackets (because everything must have a value, and the last value will be used).

When the interpreter reaches line 3, it finds another perfectly valid expression ruby, + b . Since + 5 ( 5 is the value of the variable b ) is a declaration of the VALID integer value in ruby, the interpreter considers it autonomous, not related to the previous 5 , evaluated for the variable a (remember, it had no other expectation than what was in brackets ) In short, it throws away the value obtained for a and uses only the value obtained with + b . In the next line, he finds the enclosing parenthesis, and therefore the expression in brackets is assigned the last produced value, which is 5 , expressed by the expression + b .

Since the interpreter finds / in line 4, it (correctly) understands it as a method of integer division, since it has produced an integer so far (int 5 )! This creates an expectation of the possible arguments of the method, which it finds in line 5. The resulting computed expression y = 5 / 2 , which is 2 in integer divisions. So basically, here is what the interpreter did:

 y = ( # Ok, i'm waiting for the rest of the parenthesis expression a # cool, a has value 5, if the parenthesis ends here, this is the value of the expr. + b # Oh, but now I found + b, which has value + 5, which evaluates to 5. So now this is the last value I have evaluated. ) / # Ok, the parenthesis have been closed, and the last value I had was a 5. Uow, wait, there is a slash / there! I should now wait for another argument for the / method of the 5 I have! 2 # Found, let make y = 5 / 2 = 2! 

The problem is that on line # 2 you should have expected the wait for the interpreter (just like you left on line 4 with the / method), which you did not!

Answer @ Mauricio Linares suggests exactly this:

 y = ( a + b ) / 2 

By moving the + method to the end of line 2, you tell the interpreter that your expression is not yet complete! Therefore, it keeps waiting and goes to line # 3 to find the correct operand of the expression (or, more precisely, in Ruby, the argument for the + : D method).

The same thing works with string concatenation:

 # WRONG, SINCE + "somestring" is not a valid stand-alone expression in ruby str = "I like to" + " move it!" # NoMethodError: undefined method ` +@ ' for " move it!":String # CORRECT, by leaving the + sign as last statement of the first line, you # keep the 'expectation' of the interpreter for the next # argument of the + method of the string object "I like to" str = "I like to" + " move it!" # => "I like to move it!" 

The difference is that no errors were detected in your code, since + b is indeed a valid expression.

I hope my answer was useful in order to give you some intuition about why this does not work, as expected, sorry if I'm not brief :)

+2
source

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


All Articles