问题描述
在使用新的 case ... in
pattern matching in Ruby 时,有没有好的方法可以防止将 nil
绑定到变量?
case method()
in ... # Some cases here
...
in ...
...
in variable # If prevIoUs clauses did not match,then capture to variable
puts variable
else # How to prevent that variable also captures nil?
puts "Nil" # -> This is not called if method() returns nil
end
我发现了以下两种方法,但它们看起来有点难看:
1.) 使用 if
限定符
case method()
in ... # Some cases here
...
in ...
...
in variable if variable
puts variable
else
puts "Nil"
end
2.) 反向匹配顺序
case method()
in ... # Some cases here
...
in ...
...
in nil
puts "Nil"
in variable # Catch all
puts variable
end
有什么更好的吗?
这也能用吗?这将提供一种使用单行模式匹配表达式对 nil
进行比较和赋值的好方法:
if method() => variable
...
end
(这个问题的灵感来自于a question on assignments in if statements)
解决方法
匹配无赋值的 NilClass
如果您决定忽略 nil
,您可以通过简单地匹配 NilClass 然后不分配结果来实现。在调用 as-pattern(例如 in variable
)或 else 子句之前执行此操作。例如:
# arg can be assigned `nil` but can't be unassigned; this
# ensures that any nil values were actually passed in
def pattern_match arg
case arg
in /^a$/ => bar
in NilClass
in bar
end
# We print a message here to differentiate between arg and
# bar being `nil`,because otherwise the method simply
# returns `nil` since bar is auto-vivified by the
# interpreter when it evaluates the case statement. This is
# a potential source of confusion when looking at the
# results.
bar || 'matched NilClass'
end
# pass values through a scope gate for testing each
# assignment to bar in isolation
[?a,'str',1,nil].map { pattern_match _1 }
#=> ["a","str","matched NilClass"]