ruby - 如果值不为零,有条件地在 Ruby 中执行 block ? (又名 Smalltalk 的 ifNotNilDo :)

标签 ruby design-patterns block smalltalk

在 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/

相关文章:

.net - 设计模式...从哪里开始? (一些实际示例)

sql - Oracle:什么是单 block 与多 block IO

ruby - 如何使用 elsif 和范围?

ruby-on-rails - 向模型添加新列

ruby - 无法加载我的 Ruby 文件

java - 为应用程序实现一个通用的观察者模式/监听器

ruby-on-rails - Delayed_Jobs 不会刷新

java - 迭代集合时的数据累积设计

java - Eclipse 格式化。在为 block 打开大括号之前删除新行

javascript - Facebook 被屏蔽,显示替代内容?