代码之家  ›  专栏  ›  技术社区  ›  Edmund Lee

在ruby中&&=操作符是片状的?

  •  0
  • Edmund Lee  · 技术社区  · 8 年前

    在Ruby中遇到了一个奇怪的行为。不知道是不是只有我。我使用的是ruby 2.3.3。这是日志。按顺序操作它们,你应该能够复制它。

    [1] pry(main)> a &&= nil.a
    => nil
    [2] pry(main)> a &&= 1.to_s
    => nil
    [3] pry(main)> a = 1 && 1.to_s
    => "1"
    [4] pry(main)> a &&= 1.to_s
    => "1"
    [5] pry(main)> a &&= nil.a
    NoMethodError: undefined method `a' for nil:NilClass
    from (pry):5:in `__pry__'
    

    看看 1 和[5],以及 2 和【4】

    编辑:

    有一个 similar question on SO . 和a blog post 这就是为什么。但我认为他们无法解释。

    SO thread ,它说 &&= 是的快捷方式 x = x && y if x . 但考虑一下:

    num = 1
    a &&= num.to_s
    # => nil
    

    vs公司

    num = 1
    a = num && num.to_s if num
    # => "1"
    

    在ruby中,如果 a 未定义, a = a 给你 nil . x=x(&&如果x为y 这本身就是一种奇怪的操作。

    x = x && y if x
    

    这应与以下内容相同

    if x
      x = x && y
    end
    

    但这会引发一个错误,因为 x 未定义。那么,哪个部分实际上是首先评估的?它是 x = x && y if x ?

    1 回复  |  直到 8 年前
        1
  •  8
  •   Community Mohan Dere    8 年前

    值得注意的是,关于 &&= :

    • 始终考虑左侧的变量 定义 是否实际进行了分配。
    • 定义的变量假定值为 nil 如果没有明确指定值。
    • 只有在以下情况下,才计算右侧的术语 a 逻辑上正确,或者更具体地说,如果 不是其中之一 false .
    • 因此,如果 逻辑上是不正确的,那么右侧只需 语法有效 ,因为它不会得到评估。这意味着像 nil.a 在这些特定条件下是可以接受的,它将被解析,但在其他情况下会被忽略。
    • 如果 错误 那么 未更改。

    的长格式版本 a &&= b 实际上是:

    a = if (a)
      b
    else
      a
    end
    

    哪里 b 可以是任何表达式,包括 a &&= b &&= c

    对于您的示例,这与表达式的右侧是否得到计算有关。在第一种情况下 是未定义的,所以不会。

    稍后,当您实际定义 作为某种东西,它必须在右侧执行,因此您最终需要评估 无一 然后它爆炸了。

    在这种情况下,您可以执行任何操作:

    nil && whatever(this!, will!, not!, ever!, run!)
    

    这并不奇怪,只是表现得不像你想象的那样。 && 是其中之一 短路 评价的。即:

    a && b && c && d
    

    实际解释为:

    if a
      if b
        if c
          d
        end
      end
    end
    

    因此,在这种表述中,很明显,如果其中任何一个条件失败,它就会退出并跳过其余的条件。

    需要注意的一点是 使用弹出窗口 &&= 自动:

    local_variables
    # => [:_]
    a &&= true
    # => nil
    local_variables
    # => [:a,:_]
    

    这与 && .

    推荐文章