在Ruby中编写多行算术

时间:2014-06-15 00:16:06

标签: ruby

如何在Ruby中正确编写多行算法?以前,我尝试过类似y的东西,然后我意识到代码有问题。由于我很长的等式,我需要编写多行算术。

a = 5
b = 5

x = (a + b) / 2

puts x # 5, as expected

y = (
      a
      + b
    ) /
    2

puts y # 2, what happened?

3 个答案:

答案 0 :(得分:10)

如果语句看起来已经在行尾结束,那么Ruby解析器将假定语句已经结束。

你可以做的是阻止算术运算符在新行之前,如下所示:

a = 1
b = 2
c = a + 
    b

你会得到你期望的结果。

答案 1 :(得分:3)

(
  expr1
  expr2
 )
实际上,在Ruby中,

相同
(expr1; expr2)

只执行第一个表达式(副作用)并返回第二个表达式(也在评估后)

答案 2 :(得分:2)

尝试考虑解释器的“期望”,并记住在ruby中,一切都是一个表达式(这意味着一切都评估为某些值,甚至构造在其他语言中被认为是“特殊的”,如果 - 然后 - elses,loops,etcettera)。

所以:

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

在第1行,我们开始声明一个变量,该行以一个打开(挂起)括号结束。解释器需要定义的其余部分,因此它将进入下一行,寻找要分配给var y的VALUE。

在第2行,解释器找到变量a,但没有括号。它评估a,其值为5,并且由于第2行是完全有效的表达式,解释器理解该表达式已完成(因为在Ruby中,换行符OFTEN表示表达式结束指示符)。 所以到目前为止它已经产生了一个值5,但它唯一的期望是它必须与括号括起来。

如果之后解释器找到了括号,它会将a (i.e. 5)的值赋给括号表达式(因为所有内容都必须有一个值,并且将使用最后生成的值)。

当解释器到达第3行时,它会找到另一个完全有效的ruby表达式+ b。由于+ 55是变量b的值)是ruby中的VALID整数声明,因此解释器将其视为独立的,与之前的5完全无关评估变量a(记住,它没有其他期望,除了括号之外)。 简而言之,它会丢弃a获得的值,并仅使用+ b获得的值。在下一行中,它找到括号,因此括号表达式被赋予最后生成的值,即由5表达式生成的+ b

从第4行开始,解释器找到/,它(正确地)将它理解为整数的除法方法,因为它到目前为止已经生成了一个整数(int 5)!这创建了对方法的可能参数的期望,它在第5行找到。得到的计算表达式为y = 5 / 2,等于整数除法中的2。所以,基本上,这是解释器的作用:

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's make y = 5 / 2 = 2!

这里的问题是,在第2行,您应该对解释器留下一个期望(正如您使用/方法在第4行留下的那样),而您没有![/ p>

@MaurícioLinhares的回答恰恰说明了这一点:

y = (
  a +
  b
) /
2

通过将+方法移动到第2行的末尾,您告诉解释器您的表达式仍未完成!因此它保持期望并继续到第3行以找到表达式的正确操作数(或者更确切地说,在Ruby中,+方法的参数:D)。

同样适用于字符串连接:

# 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!" 

不同之处在于,在您的代码中没有抛出任何错误,因为+ b实际上是一个有效的表达式。

我希望我的答案对于给你一些关于为什么没有按预期工作的直觉很有用,对不起,如果我不简洁:)