在 Smalltalk 中有方法 ifNotNilDo:
它是这样使用的:
database getUser ifNotNilDo: [:user | Mail sendTo: user ]
在不是nil
的对象上执行 block ,将对象本身作为参数传递。 UndefinedObject
类(Smalltalk 等同于 Ruby 的 NilClass
)中的实现什么也不做。这样,如果获取用户的结果是 nil
对象,则什么也不会发生。
我不知道 Ruby 有类似的东西,所以我推出了自己的解决方案。 它是这样的:
class Object
def not_nil
yield(self)
end
end
class NilClass
def not_nil
# do nothing
end
end
可以这样使用:
users = {:peter => "peter@peter.com", :roger => "roger@roger.com" }
users[:roger].not_nil {|u| Mail.send(u) }
这使我们免于访问哈希两次
Mail.send(users[:roger]) if users[:roger]
...或使用临时变量:
u = users[:roger]
Mail.send(u) if u
更新:
人们开始建议基于散列操作的解决方案,并且还两次访问散列。我的问题不直接与哈希相关。
想象一下,第一个操作不是哈希访问,而且也很昂贵。喜欢:
RemoteUserRepo.find_user(:roger).not_nil {|u| Mail.send(u) }
(更新结束)
我的问题是:
- 重新发明这个成语我错了吗?
- 开箱即用的 Ruby 是否支持这样的(或更好)?
- 或者是否有另一种更短、更优雅的方法?
最佳答案
在 Ruby 2.3.0+ 中,您可以将安全导航运算符 (&.
) 与 Object#tap
结合使用:
users[:roger]&.tap { |u| Mail.send(u) }
关于ruby - 如果值不为零,有条件地在 Ruby 中执行 block ? (又名 Smalltalk 的 ifNotNilDo :),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26577411/