Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby习惯用法:方法调用或默认值_Ruby_Methods_Default_Idioms - Fatal编程技术网

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是构建自下

用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'