我正在寻找一个可以执行以下操作的函数:
def self.my_find
object = self.first #Whatever
return object.my_check? ? object : nil
end
类似
check
:
object.check(&:my_check?)
它应该存在,不是吗?
这是我的情况:
在方法(控制器)中,我有一些
nil
可用的对象,我需要检查对象上的某些内容以进一步使用它。
如果尝试编写伪功能代码,逻辑首先是检索对象,然后对对象执行操作,然后返回这些操作。
如果我有一个集合,代码将是:
result = get_my_collection_method.select(&:my_check?).map(&:my_action)
如果
select
方法过滤所有对象,那么 result
将等于 []
,但代码仍然有效。
我发现想要做同样的事情是很自然的,即使它不是一个集合而是一个单一的对象:
result = get_my_object.check(&:my_check?).try(:my_action)
但是这个方法不存在的事实告诉我,Ruby 中的对象和数组之间没有一元转换。
我想实现这一点的最简单方法是将我的单例转换为单值数组:
result = Array(get_my_object).select(&:my_check?).map(&:my_action).first
我希望这能澄清为什么我一直在寻找这样的方法。
但问题仍然存在:它本身就存在吗?如果我自己编写(即使在
Object
级别),这不是标准,我失去了编写干净代码的好处。
虽然这样的方法在您的特定情况下可能看起来很有用,但这种事情通常表达如下:
object = self.first
object.my_check? and object
据了解,此方法可能会返回
false
但这不是逻辑上的真值,所以没关系。
如果您想为对象编写自己的方法来执行此操作,欢迎您这样做,但请记住,您的代码越深奥和古怪,其他人就越难参与。当你忘记了你不寻常的核心扩展时,那些“其他人”可能就是未来的你。
有以下几种方法:
def self.my_find
object = self.first # Whatever
# Use ONE of the following examples:
# 1.
object if object.my_check?
# 2.
object.my_check? && object
# 3.
object.my_check? ? object : nil
end
请注意,在 ruby 中的方法末尾不需要显式的
return
。
根据上下文(我只能推测,因为没有给出!),可能有一种更干净的方法来做到这一点。例如,如果这实际上是您在 Rails 应用程序中构建的内容,那么以下示例之一会更好:
def self.my_find
where(...).find_by(my_check: true)
# Or, where `my_check` is a *SCOPE*!!
my_check.find_by(...)
end
...关键区别在于您是在 SQL 中而不是在 ruby 中执行检查。这提供了更好的性能。
self.first.tap{ |obj| break unless obj.my_check? }