我是Ruby新手。有没有办法写一个单一的def阵列/范围/哈希'使用method_missing将适用于所有范围,数组和哈希,即所有 Enumerables ?对于例如以下应该有效:
[1..5].Sum()
[1,2,3,5].Sum()
{'x' => 1, 'y' = 4}.Sum()
Sum()是我在method_missing中定义的自定义方法 。截至目前,我已经编写了三个不同的函数来分别处理Array,Range和Hash的method_missing。
答案 0 :(得分:4)
您可以通过打开method_missing
模块并为其添加实例方法来为所有Enumerables定义Enumerable
:
module Enumerable
def method_missing *args
puts 'hi'
end
end
[].hithere # => hi
但我建议定义具体的sum
方法(根据Ruby方法命名指南以小写字母开头),而不是将此逻辑添加到method_missing
:
module Enumerable
def sum
# your implementation
end
end
[].sum
答案 1 :(得分:0)
正如Alex所说,最好的方法是为Enumerable定义自己的方法#sum, 然而,虽然每个Enumerable都应该有#each,但它产生的每个子类都不同。例如,Hash产生一个键值对,您的单个#sum方法必须知道如何处理。
这是一个如何实现它的例子,它试图将传入的参数splat到一个数组中,而sum只包含数组的最后一个元素。这适用于Hashes,Array和Ranges(但它可能仅适用于1.9)
module Enumerable
def sum
r = 0
each {|(*x)| r += x.last}
r
end
end
或者,您可以为每个Enumerable定义自己的迭代方法,例如#each_for_sum,让#sum使用该方法进行求和。但是你可能不得不为不同的Enumerables写几个版本的#each_for_sum(例如,默认的#each_for_sum只是Enumerable#each,但是Hash#each_for_sum只会产生值。)
module Enumerable
def sum
r = 0
each_for_sum {|x| r += x}
r
end
def each_for_sum &block
each(&block)
end
end
class Hash
def each_for_sum
values.each {|x| yield x}
end
end