Kev*_*cha 3 ruby enums ruby-on-rails
在我使用的rails应用程序中非常常见的错误之一是nil类错误.具体来说,我经常看到像"NoMethodError:undefined方法`每个'为nil:NilClass"的错误.
这些都很烦人,通常是良性的,并且在整个地方挤满了可怕的无法检查代码.
这是一个例子:
[3] pry(main)> def test(enum)
[3] pry(main)* enum.each { |x| puts x }
[3] pry(main)* end
=> nil
[4] pry(main)> test(nil)
NoMethodError: undefined method `each' for nil:NilClass
from (pry):2:in `test'
[5] pry(main)>
Run Code Online (Sandbox Code Playgroud)
如果我只是输入一个返回除非枚举,或者返回除非responds_to?(:each).但是,如果我不希望这些检查混淆我的代码怎么办?
好吧,我想到了一个想法,我想知道这是不是一个坏主意.
[5] pry(main)> class NilClass
[5] pry(main)* include Enumerable
[5] pry(main)*
[5] pry(main)* def each; end
[5] pry(main)* end
=> nil
[6] pry(main)> test(nil)
=> nil
[7] pry(main)>
Run Code Online (Sandbox Code Playgroud)
我无法想象任何库依赖于nil上的NoMethodError来驱动逻辑(如果他们这样做听起来像我不应该使用的库).此外,这提供了各种好处,因为现在可以使用整个枚举方法:
[12] pry(main)> Enumerable.public_instance_methods(false).each { |method| puts "#{method.to_s.ljust(20)} => #{nil.send(method) {} }" if nil.method(method).parameters.empty? }
to_a => []
sort => []
sort_by => []
find_all => []
select => []
reject => []
collect => []
map => []
flat_map => []
collect_concat => []
partition => [[], []]
group_by => {}
all? => true
any? => false
one? => false
none? => true
min =>
max =>
minmax => [nil, nil]
min_by =>
max_by =>
minmax_by => [nil, nil]
take_while => []
drop_while => []
lazy => #<Enumerator::Lazy:0x007f84623c9d38>
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
我应该这样做吗?
编辑1
我想指出函数式语言(和rust)通常不会实现nil类.我的实际意图是将Nil变为空集,以便对nil的操作表现得像一个空集.
具体来说,我经常看到像"NoMethodError:undefined方法`每个'为nil:NilClass"的错误.
[...]
如果我只是输入一个返回除非枚举,或者返回除非responds_to?(:each).
[...]
我应该这样做吗?
绝对不.如果该错误经常发生,那么这意味着您的代码测试不佳且开发不佳.
频繁使用NoMethodError意味着您未能正确处理输入中收到的数据,应将其视为您需要修复的错误,而不是沉默.
解决方案是开始隔离崩溃的每段代码.编写一个重现错误的测试并相应地处理输入.如果您希望传递一个值并传递一个nil,那么您需要了解为什么存在nil,修复代码并确保使用测试来避免回归.
| 归档时间: |
|
| 查看次数: |
95 次 |
| 最近记录: |