Ruby2.3之前的版本与安全导航运算符(&amp ;.或"&&-点")等效吗? [英] What is the pre-Ruby2.3 equivalent to the safe navigation operator (&. or "ampersand-dot")?

查看:119
本文介绍了Ruby2.3之前的版本与安全导航运算符(&amp ;.或"&&-点")等效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能找到的每个问题的答案(第一季度Q2 )新的安全导航运算符(&.)错误地声明obj&.foo等效于obj && obj.foo.

The answers to every question I can find (Q1, Q2) regarding Ruby's new safe navigation operator (&.) wrongly declare that obj&.foo is equivalent to obj && obj.foo.

很容易证明这种等效是不正确的:

It's easy to demonstrate that this equivalence is incorrect:

obj = false
obj && obj.foo  # => false
obj&.foo        # => NoMethodError: undefined method `foo' for false:FalseClass

此外,存在多重评估的问题.用具有副作用的表达式替换obj时,表明仅在&&表达式中,副作用才翻倍:

Further, there is the problem of multiple evaluation. Replacing obj with an expression having side effects shows that the side effects are doubled only in the && expression:

def inc() @x += 1 end

@x = 0
inc && inc.itself  # => 2

@x = 0
inc&.itself        # => 1

避免出现这些问题的,与obj&.foo相同的最简洁的2.3版之前是什么?

What is the most concise pre-2.3 equivalent to obj&.foo that avoids these issues?

推荐答案

Ruby 2.3中的安全导航运算符的工作原理与

The safe navigation operator in Ruby 2.3 works almost exactly the same as the try! method added by ActiveSupport, minus its block handling.

它的简化版可能看起来像这样:

A simplified version of that could look like this:

class Object
  def try(method, *args, &block)
    return nil if self.nil?
    public_send(method, *args, &block)
  end
end

您可以像这样使用

obj.try(:foo).try(:each){|i| puts i}

try方法实现了安全导航操作符的各种详细信息,包括:

This try method implements various details of the safe navigation operator, including:

  • 如果接收方为nil,则始终返回nil,而不管nil是否实际实现了所查询的方法.
  • 如果非nil接收者不支持该方法,则会引发NoMethodError.
  • 它不会吞下方法调用上的任何异常.
  • It always returns nil if the receiver is nil, regardless of whether nil actually implements the queried method or not.
  • It raises a NoMethodError if the non-nil receiver doesn't support the method.
  • It doesn't swallow any exceptions on method calls.

由于语言语义上的差异,它不能(完全)实现真正的安全导航运算符的其他功能,包括:

Due to differences in language semantics, it can not (fully) implement other features of the real safe navigation operator, including:

  • 与安全导航运算符相比,我们的try方法始终评估其他参数.考虑这个例子

  • Our try method always evaluates additional arguments, in contrast to the safe navigation operator. Consider this example

nil&.foo(bar())

在这里,不评估bar().当使用我们的try方法作为

Here, bar() is not evaluated. When using our try method as

nil.try(:foo, bar())

我们总是首先调用bar方法,无论以后是否使用它调用foo.

we always call the bar method first, regardless of whether we later call foo with it or not.

请注意,当在生产环境中实际实现此代码时,应查看改进,而不是修补核心类.

Note that when actually implementing this code in production, you should have a look at Refinements instead of patching core classes.

这篇关于Ruby2.3之前的版本与安全导航运算符(&amp ;.或"&&-点")等效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆