合并数组时继承自定义方法
Inherit custom methods when merging arrays
我在数组实例上定义了一些自定义方法,例如:
a = [1, 2]
b = [3, 4]
a.define_singleton_method(:foo) do
"foo"
end
a.foo
# => "foo"
是否可以传递/继承/保留这个自定义方法,当a
数组被添加到另一个数组(或任何其他数组操作如uniq,交集...) 例如:
(a + b).foo
# undefined method `foo' for [1, 2, 3, 4]:Array (NoMethodError)
这是有道理的,因为创建了一个新数组。但是我想知道是否有一种方法可以在新创建的数组上保留 a
数组上的自定义方法。
当然,我可以通过调用 define_singleton_method
的相同步骤传递每个数组,但这会变得非常复杂,您很容易忘记一个数组。
你可以写一个Array
的ViralArray
子类,它覆盖每个Array
方法来产生一个新的数组,其中包括你的额外方法.
class ViralArray < Array
[:+, :*, :-].each { |method|
define_method(method) do |*args|
new_array = super(*args)
new_array.define_singleton_method(:foo) do
"foo"
end
new_array
end
}
end
my = ViralArray[1,2,3]
b = my + [4,5,6]
p b.foo # "foo"
p b.class # Array
这显然很乏味并且容易损坏。
但是像这样的病毒式方法使得代码很难理解。你永远不知道哪些数组有#foo,哪些没有。
相反,refine
Array。细化就像猴子修补,但范围有限。
定义 Array
的细化,添加 #foo
.
module FooArray
refine Array do
def foo
"foo: #{object_id}"
end
end
end
并在需要使用 foo
方法的数组的代码中使用它。
using FooArray
a = [1,2,3]
puts a.foo
所有其他代码将不受影响。
我在数组实例上定义了一些自定义方法,例如:
a = [1, 2]
b = [3, 4]
a.define_singleton_method(:foo) do
"foo"
end
a.foo
# => "foo"
是否可以传递/继承/保留这个自定义方法,当a
数组被添加到另一个数组(或任何其他数组操作如uniq,交集...) 例如:
(a + b).foo
# undefined method `foo' for [1, 2, 3, 4]:Array (NoMethodError)
这是有道理的,因为创建了一个新数组。但是我想知道是否有一种方法可以在新创建的数组上保留 a
数组上的自定义方法。
当然,我可以通过调用 define_singleton_method
的相同步骤传递每个数组,但这会变得非常复杂,您很容易忘记一个数组。
你可以写一个Array
的ViralArray
子类,它覆盖每个Array
方法来产生一个新的数组,其中包括你的额外方法.
class ViralArray < Array
[:+, :*, :-].each { |method|
define_method(method) do |*args|
new_array = super(*args)
new_array.define_singleton_method(:foo) do
"foo"
end
new_array
end
}
end
my = ViralArray[1,2,3]
b = my + [4,5,6]
p b.foo # "foo"
p b.class # Array
这显然很乏味并且容易损坏。
但是像这样的病毒式方法使得代码很难理解。你永远不知道哪些数组有#foo,哪些没有。
相反,refine
Array。细化就像猴子修补,但范围有限。
定义 Array
的细化,添加 #foo
.
module FooArray
refine Array do
def foo
"foo: #{object_id}"
end
end
end
并在需要使用 foo
方法的数组的代码中使用它。
using FooArray
a = [1,2,3]
puts a.foo
所有其他代码将不受影响。