Ruby习惯用法:方法调用或默认值
用Ruby做这件事的正确方法是什么Ruby习惯用法:方法调用或默认值,ruby,methods,default,idioms,Ruby,Methods,Default,Idioms,用Ruby做这件事的正确方法是什么 def callOrElse(obj, method, default) if obj.respond_to?(method) obj.__send__(method) else default end end 我可能会选择 obj.respond_to?(method) ? obj.__send__(method) : default 所以您想要类似于x=obj.method | | default?Ruby是构建自下
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
我可能会选择
obj.respond_to?(method) ? obj.__send__(method) : default
所以您想要类似于
x=obj.method | | default
?Ruby是构建自下而上结构的理想语言:
class Object
def try_method(name, *args, &block)
self.respond_to?(name) ? self.send(name, *args, &block) : nil
end
end
p "Hello".try_method(:downcase) || "default" # "hello"
p "hello".try_method(:not_existing) || "default" # "default"
也许你不喜欢这种带有符号的间接呼叫?没问题,然后查看的maybe
样式并使用代理对象(您可以找出实现):
旁注:我不是OOP专家,但我的理解是,您应该事先知道您正在调用的对象是否确实有这样的方法。或者
nil
是您想要控制不向其发送方法的对象吗?在这种情况下,Ick已经是一个很好的解决方案:object_或_nil.maybe.method | | default
,因为它还没有作为答案提供:
result = obj.method rescue default
与@slhck一样,当我知道obj很可能不会响应该方法时,我可能不会使用该方法,但这是一个选项。您可以这样做:
object&.method(n) || 'default'
“&”在这里充当Maybe。也许它有什么,也许它没有。当然,如果没有,它将只返回nil,并且不会运行后面的方法。这更干净,但本质上是相同的功能。我认为会有更好的方法来实现这一点。那么,如果没有相同的功能,您想要什么呢?:)就我而言,没有办法绕过这个决定。但是也许有人有一个想法。我希望得到类似这样的东西:
x=obj.method | | default
。如果你真的想要,你可以覆盖method\u missing
,返回nil
,但我建议不要这样做。EAFP(即,在这里使用try除外)在Ruby社区中没有像Pythonistas那样受到欢迎吗?@Karl。我并不是在为所有Ruby程序员说话,但是对于许多Ruby程序员来说,必须(至少)为一个Ruby中可以完成的事情编写四行代码是非常烦人的(尽管在Python中他们可能不会介意)。此外,如果OP想要包含默认行为,我不会在这里使用try/except结构。在我看来,如果两种方式(即send
和default
)都可以发生,为什么要将其设为“例外”?这通常是一个很好的答案,但请注意,实现将导致任何返回false
或nil
的现有方法改用“default”。@Phrogz:这是一个很好的观点,但在这种情况下,不太可能需要默认值,只需编写条件“if obj.maybe.enabled?”。无论如何,您可以根据自己的需要调整maybe模式:“obj.maybe(:default=>true.active?”,但是“| | default”应该涵盖典型情况。虽然简单,但这有一个主要缺点,即隐藏obj.method引发的任何异常,您将不知道它是否没有方法或只是失败了。我个人会尽可能避免就地救援。-1因为@tokland提到的原因。你真的不能把它作为一个通用的策略。这是一个新版本的东西还是rails
的东西?在pry上尝试了它,但在Ruby 2.3中添加了安全导航操作符&.
之前,它为main:Object`@显示了name错误:未定义的局部变量或方法。不过,这在这里并不合适,它是用来避免nil
检查而不是一般的缺失方法(即o&.m
是o.nil??nil:o.m
,而不是o.response to(:m)?o.m:nil
)。@muistooshort得到了,谢谢你向我解释:)@Tiw是正确的。它用于避免零支票。无论如何,对于这样的事情,最好的模式是使用
object&.method(n) || 'default'