我只是闯入红宝石世界,我可以伸出援助之手。
假设b
为nil
。
我希望以下代码返回nil
而不是“NoMethodError:undefined method”
a.b.c("d").e
我尝试的第一件事就是将NilClass的missing_method重载为简单的返回nil。这是我想要的行为,除了我不想成为这种侵扰行为。
如果我可以做这样的话,我会喜欢它
SafeNils.a.b.c("d").e
所以它就像是一种干净的方式来局部地重载NilClass的行为。
我很想听到一些想法或很多资源来挖掘这个。我对其他方法也很开放,只要它相当干净。
非常感谢。
答案 0 :(得分:6)
我认为您可以在rails中找到一个很好的解决方案,但该解决方案遵循不同的方法。看一下try方法。这是一个干净的方法。
答案 1 :(得分:5)
您可以使用inline rescue:
x = a.b.c("d").e rescue nil
如果x
为nil
, b
将为nil
。
或者,正如有人在该链接中发表评论,您可以使用andand gem(请参阅docs):
x = a.andand.b.andand.c("d").andand.e
答案 2 :(得分:3)
begin
a.b.c("d").e
rescue NoMethodError=>e
return nil
end
答案 3 :(得分:3)
答案 4 :(得分:2)
提前备注: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
a.b.c("d").e
但我认为,救援可能会更好地满足您的需求:
class A
def b
nil
end
end
a = A.new
x = begin a.c.c("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 = a.b.c("d").e
p x
puts x
p x.nil?
答案 5 :(得分:1)
使用类似于您所写的safe_nils
:
def safe_nils &blk
return blk.call
rescue NoMethodError
return nil
end
safe_nils { a.b.c("d").e }
答案 6 :(得分:0)
我为此制作了may_nil
宝石。 https://github.com/meesern/may_nil
与@Sony Santos的safe_nils一样,它使用一个块来包装方法链并拯救NoMethodError,但会检查nil(因此会为其他类正确引发异常)。
require `may_nil`
may_nil {a.b.c("d").e} => nil (or the end result)
may_nil {0.b.c("d").e} => Exception: NoMethodError (b on Fixnum)
与andand
或ike
的{{1}}不同,您不需要对方法链加密。
maybe
答案 7 :(得分:0)
一种方法是对局部变量使用内联赋值:
a && (ab = a.b) && (abcd = ab.c("d")) && abcd.e
对于你所拥有的链条而言,它不是很优雅,但对于较短的链条,它可能很有用:
def date_updated(entry)
(updated = entry.updated) && updated.content
end
答案 8 :(得分:0)
从ruby v2.3.0开始,该语言内置了另一种方法,即安全导航操作员(&amp ;.)
您可以写:a&.b&.c&.d
如果链中的一个调用返回nil,您将安全地获得nil。
你可以在这里读更多关于它的内容:
http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/