有没有一种方法可以覆盖对象上的&方法,以便在调用时返回一个数组,如下所示:
class MyObject
end
o1, o2, o3 = MyObject.new, MyObject.new, MyObject.new
o1 # => #<MyObject0x01>
o1 & o2 # => [#<MyObject0x01>, #<MyObject0x02>]
o1 & o2 & o3 # => [#<MyObject0x01>, #<MyObject0x02>, #<MyObject0x03>]发布于 2011-01-02 15:45:50
试图让你自己的语法看起来很愚蠢。为什么不直接使用Ruby的数组表示法呢?
[o1, o2, o3] # => [#<MyObject0x01>, #<MyObject0x02>, #<MyObject0x03>]我是不是忽略了什么显而易见的东西?
发布于 2011-01-02 18:08:01
答案很简单,不是。冗长的答案是,如果你返回一个数组,你将打破MyObject的引用链,然后开始调用数组上的方法。基于The Principal of least surprise的最优排序解决方案
阵列使用[] << o1 << o2 << o3或表现得像阵列
class MyObjectCollection <数组定义&#做我想说的end
引用链的解释
class MyObject
end
o1, o2, o3 = MyObject.new, MyObject.new, MyObject.new
o1 # => #<MyObject0x01> # <-- works
o1 & o2 # => [#<MyObject0x01>, #<MyObject0x02>] # <-- could work with def & because the LHS is a MyObject
o1 & o2 & o3 # => [#<MyObject0x01>, #<MyObject0x02>, #<MyObject0x03>] # <--- CANNOT work because o1 & o2 return an object of type Array and not of type MyObject发布于 2011-01-03 01:47:21
阅读所有其他答案,了解重要细节。但这里有一个解决方案:
class MyObject
def initialize(x)
@x = x
end
def &(arg)
return [self, arg]
end
def to_s
@x
end
end
class Array
def &(arg)
if arg.is_a? MyObject
return self << arg
else
# do what Array.& would normally do
end
end
end
a = MyObject.new('a')
b = MyObject.new('b')
c = MyObject.new('c')
x = a & b & c
puts x.class
puts "[#{x.join(', ')}]"这是另一个更安全的解决方案(即不使用monkeypatching):
class MyObject
def initialize(x)
@x = x
end
def &(arg)
a = MyObjectArray.new
a << self << arg
end
def to_s
@x
end
end
class MyObjectArray < Array
def &(arg)
return self << arg
end
end
a = MyObject.new('a')
b = MyObject.new('b')
c = MyObject.new('c')
x = a & b & c
puts x.class
puts "[#{x.join(', ')}]"https://stackoverflow.com/questions/4577535
复制相似问题