改进是对 v2.0 的实验性补充,然后在 v2.1 中进行了修改并永久化。通过提供“一种在本地扩展类的方法”,它提供了一种避免“猴子补丁”的方法。
我试图申请Refinements
这个最近的问题,我将因此简化:
a = [[1, "a"],
[2, "b"],
[3, "c"],
[4, "d"]]
b = [[1, "AA"],
[2, "B"],
[3, "C"],
[5, "D"]]
如果:i
_ a
_ i
_b
a[i].first == b[i].first
和
a[i].last.downcase == b[i].last.downcase
换句话说,字符串的匹配与大小写无关。
问题是确定a
与 的对应元素匹配的元素数量b
。我们看到答案是两个,偏移量1
和的元素2
。
一种方法是猴子补丁String#==:
class String
alias :dbl_eql :==
def ==(other)
downcase.dbl_eql(other.downcase)
end
end
a.zip(b).count { |ae,be| ae.zip(be).all? { |aee,bee| aee==bee } }
#=> 2
或者改为使用Refinements
:
module M
refine String do
alias :dbl_eql :==
def ==(other)
downcase.dbl_eql(other.downcase)
end
end
end
'a' == 'A'
#=> false (as expected)
a.zip(b).count { |ae,be| ae.zip(be).all? { |aee,bee| aee==bee } }
#=> 0 (as expected)
using M
'a' == 'A'
#=> true
a.zip(b).count { |ae,be| ae.zip(be).all? { |aee,bee| aee==bee } }
#=> 2
但是,我想这样使用Refinements
:
using M
a.zip(b).count { |ae,be| ae == be }
#=> 0
但是,如您所见,这给出了错误的答案。那是因为我正在调用Array#==并且细化不适用于Array
.
我可以这样做:
module N
refine Array do
def ==(other)
zip(other).all? do |ae,be|
case ae
when String
ae.downcase==be.downcase
else
ae==be
end
end
end
end
end
using N
a.zip(b).count { |ae,be| ae == be }
#=> 2
但这不是我想要的。我想做这样的事情:
module N
refine Array do
using M
end
end
using N
a.zip(b).count { |ae,be| ae == be }
#=> 0
但显然这不起作用。
我的问题:有没有一种方法可以优化String
用于Array
,然后优化Array
用于我的方法?