Nils和方法链接
我只是闯入ruby世界,我可以伸出援助之手。
假设b
nil
。
我想以下代码返回nil
而不是“NoMethodError:undefined method”
abc("d").e
我尝试的第一件事就是重载NilClass的missing_method来简单地返回一个nil。 这是我想要的行为,除了我不想成为这种侵扰。
如果我可以这样做,我会喜欢它
SafeNils.abc("d").e
所以它就像是一种干净的方式来局部地重载NilClass的行为。
我很想听到一些想法或很多资源来挖掘这个。 只要它相当干净,我也对其他方法持开放态度。
非常感谢你。
我认为您可以在rails中找到一个很好的解决方案,但该解决方案遵循不同的方法。 看看try方法。 这是一个干净的方法。
您可以使用内联救援 :
x = abc("d").e rescue nil
如果b
nil
x
将nil
。
或者,正如有人在该链接中发表评论,您可以使用andand gem (请参阅文档 ):
x = a.andand.b.andand.c("d").andand.e
检查Ick的maybe
:
abmaybe.c("d").maybe.e
或使用块:
abmaybe { |b| bc("d").e }
“尝试”非常干净,正如lucapette所说。 更一般地说,您也可以使用begin-rescue-end块,具体取决于您的情况。
begin abc("d").e rescue NoMethodError=>e return nil end
提前备注: b
是方法,而不是变量。 所以b’是’不是零,它返回零。
当’b’是一个方法时,为什么不修改b,所以它返回一些东西,什么可以处理nil。
请参阅下面的示例。
您可以定义缺少的方法:
class A def b nil end end class NilClass def c(p);nil;end def e;nil;end end a = A.new abc("d").e
但我认为,救援可能更适合您的需求:
class A def b nil end end a = A.new x = begin acc("d").e rescue NoMethodError nil end
举个例子,你可以如何定义一个类似nil的例子。
class A def b MyNil.new end end class MyNil def method_missing(m, *args, &block) if nil.respond_to?(m) nil.send(m) else self end end #Simulate nils bahaviour. def nil?;true;end def inspect;nil.inspect;end def to_s;nil;end end a = A.new x = abc("d").epx puts x p x.nil?
要使用类似于您编写的safe_nils
:
def safe_nils &blk return blk.call rescue NoMethodError return nil end safe_nils { abc("d").e }
我为此制作了may_nil
gem。 https://github.com/meesern/may_nil
就像@Sony Santos的safe_nils一样,它使用一个块来包装方法链并拯救NoMethodError,但会检查nil(因此会适当地为其他类引发exception)。
require `may_nil` may_nil {abc("d").e} => nil (or the end result) may_nil {0.bc("d").e} => Exception: NoMethodError (b on Fixnum)
与andand
或ike
不同, maybe
你不需要对方法链加油。
a.andand.b.andand.c("d").andand.e ==> may_nil{ abc("d").e }
一种方法是使用内联赋值给局部变量:
a && (ab = ab) && (abcd = ab.c("d")) && abcd.e
对于你所拥有的链条,它不是很优雅,但对于较短的链条,它可能是有用的:
def date_updated(entry) (updated = entry.updated) && updated.content end
从ruby v2.3.0开始,还有另一种内置于语言中的方法,即安全导航操作符(&。)您可以编写: a&.b&.c&.d
如果链中的一个调用返回nil,您将安全地获得nil 。 你可以在这里阅读更多相关信息: http : //mitrev.net/ruby/2015/11/13/the-operator-in-ruby/