我试图将函数作为参数传递给类的方法。我知道我需要使用proc,但我不确定我使用的是正确的语法。这是我的尝试。
module MyApp;end
module MyApp::Stats
def self.sum(a)
a.inject(0){ |accum, i| accum + i }
end
def self.mean(a)
sum(a) / a.length.to_f
end
# Many more functions....
def self.sum_proc
Proc.new{|x| sum(x) }
end
def self.mean_proc
Proc.new{|x| mean(x)}
end
# And many more procs
end
class MyData
attr_reader :values
attr_reader :aggregates
def initialize(array)
@values = array
@aggregates = {}
end
def aggregate(aggregator)
puts aggregator.call(@values)
#I would also like to create a hash of aggregator. Something like:
#aggregates["aggregator"] = aggregator.call(@values)
end
end
我可以做
ar = [1,2,3,4,5,6,7,8,9]
data = MyData.new(ar)
以各种方式调用aggregate
方法:
aggregator = Proc.new{|x| MyApp::Stats.sum(x)}
data.aggregate(aggregator)
data.aggregate(Proc.new{|x| MyApp::Stats.mean(x)} )
data.aggregate(Proc.new{|x| x.count{|y| y > 3.0} })
data.aggregate(MyApp::Stats.sum_proc)
data.aggregate(MyApp::Stats.mean_proc)
我对此代码有两个问题。首先,它似乎是多余的,因为我必须首先定义聚合器,然后是相关的proc,例如sum
和sum_proc
。其次,我想知道如何在不为其定义过程的情况下传递任何标准enumerator
方法:说count
或first
。
最后,我想为聚合器创建一个哈希,以便我可以这样做:
puts data.aggregates["sum"]
puts data.aggregates["mean"]
答案 0 :(得分:2)
方法不是Ruby中的对象。您不能将方法作为参数传递,因为您只能将对象作为参数传递。
但是,您可以通过调用method
方法并将方法的名称作为参数传递来获取表示方法的Method
代理对象。 Proc
代理对象为duck-type arity
,因此他们会回复parameters
,to_proc
,最重要的是call
和def aggregate
yield @values
end
。
将单个第一类程序作为参数的惯用方法是采用这样的块:
&
并使用一元前缀data.aggregate(&MyApp::Stats.method(:sum))
运算符传递方法:
## Linux
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 35268 117568 158244 1849104 0 0 3 11321 5 2 9 15 73 3 0