今天代码里面写了个数组链式调用,大意如下:
a = [1, 1, 2, 3, 4]
a.uniq!.reject!{|i| i % 2 == 0} #=> [1,3]
然后就掉坑里了。如下:
a = [1, 2, 3]
a.uniq!.reject!{|i| i % 2 == 0} #=>NoMethodError: undefined method `reject!' for nil:NilClass
查了文档才发现 uniq! 会在数组没有重复元素时直接返回 nil。
reject! { |item| block } → ary or nil reject! → Enumerator Equivalent to #delete_if, deleting elements from self for which the block evaluates to > true, but returns nil if no changes were made.
想当然为了简化代码写了链式调用,看来以后使用前得好好读读官方文档了。
这个不是链式调用的坑,是 api 设计的坑,这里设计的很不好
2.1.0dev :001 > [].uniq
=> []
2.1.0dev :002 > [].uniq!
=> nil
(补充:看了一下,集合操作都是这个路子,可能有原因,我结论下早了点,谁来解释一下这么设计的目的)
加 ! 标志的方法,是期望对 self 执行某个操作 (而非返回一个新的值), 因此你需要直到方法是否执行成功?当然还有另一种功用,就是相对来说执行 危险操作
的方法,也会加 ! 结尾。
! 的迭代器方法,我觉得只应该用于条件判断或循环中...