Ruby on rails 在Ruby中,赋值是否在逻辑运算符之前?

Ruby on rails 在Ruby中,赋值是否在逻辑运算符之前?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我在Ruby的if条件下遇到了一个奇怪的情况。下面是重现这种情况的示例代码 p1=/hello/ p2=/世界/ s=“你好,世界” 如果m1=s.match(p1)和&m2=s.match(p2) 放入“m1=#{m1}” 放入“m2=#{m2}” 结束 输出将是 m1=world m2=world 但是我期望的是m1=hello,因为&&操作符在Ruby操作符中包含了 此代码 if m1 = s.match(p1) && m2 = s.match(p2) 似乎被解释为

我在Ruby的
if
条件下遇到了一个奇怪的情况。下面是重现这种情况的示例代码

p1=/hello/
p2=/世界/
s=“你好,世界”
如果m1=s.match(p1)和&m2=s.match(p2)
放入“m1=#{m1}”
放入“m2=#{m2}”
结束
输出将是

m1=world
m2=world
但是我期望的是
m1=hello
,因为
&&
操作符在Ruby操作符中包含了

此代码

if m1 = s.match(p1) && m2 = s.match(p2)
似乎被解释为

if m1 = (s.match(p1) && m2 = s.match(p2))

为什么逻辑AND运算符
&&
在赋值运算符
=
之前?

在ruby中,几乎所有内容(请参阅注释)都返回一个值

运算符
&&
返回其右侧的最后一个表达式。因此
1和&3
产生3<代码>&将在第一个错误值时短路。它返回该值或最后计算的truthy表达式

||
返回其左侧的第一个表达式-因此
1 | | 3
生成1<代码>| |将在第一个真实值上短路,并返回该值

检查此差异:

1 + 5 * 3 + 1
# => 17 

1 + 5 && 3 + 1
# => 4

1 + 5 || 3 + 1
# => 6 

这是m1=s.match(p1)和m2=s.match(p2)

  • s.match(p1)
    =>“您好”
  • &&
    =>正确评估每件事
  • m2=s.match(p2)
    =>“世界”
  • m1=“你好”&&“世界”
    =>“世界”
  • 您对
    m2
    的赋值返回用于
    &&
    表达式“world”第二部分的值。ruby中的赋值也会返回一个值

    因此,m1和m2的值都是“world”。

    m1=s.match(p1)和&m2=s.match(p2)

    &&
    =
    具有更高的优先级,因此它将首先执行下面的&&操作

    s.match(p1) && m2 = s.match(p2)
    => 'hello' && m2 = 'world'
    => 'world'
    
    它将
    world
    分配给
    m2
    返回
    m2
    ,即
    world
    ,然后执行下一个分配操作

    m1={(s.match(p1)和&m2=s.match(p2))的输出}

    m1='world'

    了解

    最好使用括号使其更明确

    if (m1 = s.match(p1)) && (m2 = s.match(p2))
      ...
    end
    
    或者可以先执行赋值操作

    m1 = s.match(p1)
    m2 = s.match(p2)
    if m1 && m2
      ...
    end
    

    仅使用代码中的优先规则:

    if m1 = (s.match(p1) && m2) = s.match(p2)
    
    由于
    =
    具有从右到左的关联性,因此在尝试执行以下操作时会出现语法错误:

    (s.match(p1) && m2) = s.match(p2)
    

    “一切都返回一个值”——表达式确实如此。但是Ruby也有类似于
    break
    next
    、modifier-
    if
    、或者
    return
    本身的语句,这些语句没有返回值。(尝试将它们用作值会导致语法错误)
    if
    在满足条件时返回其正文,否则返回
    nil
    <代码>返回返回
    nil
    。是的,我认为
    break
    next
    确实没有返回,并且
    =return
    将导致语法错误。除此之外,几乎所有东西都会返回一个值。此外,您还可以在作业中使用
    =if
    ,只要它是以
    结尾关闭的。我将编辑我的答案以删除您指出的陈述。在
    true&&true | | false
    中,“&&returns the last value to right”是什么意思?“第一个值”和“最后一个值”的表达是模糊的,因此应该避免使用。在
    m1=s.match(p1)和&true中,您将同意
    s.match(p1)
    &
    之前进行评估。但是为什么呢?在答案(你的最后一段)中猜测有什么意义?读者难道不应该期望答案是确定的吗?我的答案太长,无法发表评论。我本不打算给出一个明确的答案,而是就这个问题发表了我的看法。一个问题的目的不是要引出可能的答案,直到其中一个被选为正确答案吗?我同意“第一价值”和“最后价值”是模糊的;我可能会改进这个定义和答案本身。我已经重新排列了计算顺序,因为
    s.match(p1)
    确实是在
    &&
    之前计算的。我认为这并不能完全解释这个问题。想想表达式
    (a=1&&b=2)
    ,它是有效的,并将2分配给a和b。如果我们看一下优先规则,这个表达式应该被解释为
    (a=(1&&b)=2)
    ,因为
    &&
    绑定的值高于
    =
    。但是,后者显然是错误的。@user1934428
    (a=1&&b=2)
    将被解释为
    (a=(1&&b=2))
    ,这就是它将2分配给a和b的原因b@user1934428
    &&
    将具有更高的优先级,因此它将检查左侧和右侧以执行该操作
    (a=1&&b=2)
    在本例中,左侧将是
    1
    ,右侧将是
    b=2
    。除了在本例中,a将不是1,而是2(在irb中尝试),我无法遵循您的逻辑。例如,
    *
    的优先级高于
    +
    ,而
    a+x*b+y
    ,隐式绑定是
    a+(x*b)+y
    。这就是更高优先级的含义。按照这个逻辑,
    a=1&&b=2
    如果我们只观察优先级,就会有
    a=(1&&b)=2
    。是的,因此我们不能仅用运算符优先级来解释它。我认为这也是OP提出这个问题的原因。然而,我在Ruby文档中找不到任何可以解释这种情况的东西。如果可以的话,在你的答案中包含这一点将是非常好的。你可能会觉得很有帮助。@Kaisaski:仅供参考:由于你有趣的问题没有得到令人满意的答案,我冒昧地回答了,但归结为其中的基本问题。这回答了你的问题吗?正如你所说,我认为代码会抛出一个错误。但它会返回一个意外的值。如果m1=(s.match(p1)和&m2)=s.match(p2)
    显式写入
    ,则会引发错误。但是
    如果m1=s.match(p1)和&m2=s.match(p2)
    没有。为什么我不能得到一个错误?我在猜测(找不到任何文档)