我试图用Ruby搞得一团糟.因此,我尝试从"Programming Collective Intelligence"Ruby书中实现算法(在Python中给出).
在第8章中,作者将方法a作为参数传递.这似乎适用于Python,但不适用于Ruby.
我有这个方法
def gaussian(dist, sigma=10.0) foo end
并希望用另一种方法调用它
def weightedknn(data, vec1, k = 5, weightf = gaussian) foo weight = weightf(dist) foo end
我得到的只是一个错误
ArgumentError: wrong number of arguments (0 for 1)
Daniel Lucra.. 97
关于块和过程的注释是正确的,因为它们在Ruby中更常见.但是如果你愿意,你可以传递一个方法.你打电话method
来获取方法并.call
调用它:
def weightedknn( data, vec1, k = 5, weightf = method(:gaussian) ) ... weight = weightf.call( dist ) ... end
这是有趣的.值得注意的是,在将方法名称转换为可调用符号时,只需调用一次`method(:
为了完成此操作,如果要传递在其他地方定义的方法,请执行“ SomewhereElse.method(:method_name)”。太酷了! (2认同)
Alex Wayne.. 91
你想要一个proc对象:
gaussian = Proc.new do |dist, *args| sigma = args.first || 10.0 ... end def weightedknn(data, vec1, k = 5, weightf = gaussian) ... weight = weightf.call(dist) ... end
请注意,您不能像这样在块声明中设置默认参数.因此,您需要使用splat并在proc代码中设置默认值.
或者,根据您所有这些的范围,可能更容易传递方法名称.
def weightedknn(data, vec1, k = 5, weightf = :gaussian) ... weight = self.send(weightf) ... end
在这种情况下,您只是调用在对象上定义的方法,而不是传递完整的代码块.这取决于你如何组织这个你可能需要更换self.send
与object_that_has_the_these_math_methods.send
最后但并非最不重要的,你可以挂掉方法的块.
def weightedknn(data, vec1, k = 5) ... weight = if block_given? yield(dist) else gaussian.call(dist) end end ... end weightedknn(foo, bar) do |dist| # square the dist dist * dist end
但听起来你想要更多可重复使用的代码块.
关于块和过程的注释是正确的,因为它们在Ruby中更常见.但是如果你愿意,你可以传递一个方法.你打电话method
来获取方法并.call
调用它:
def weightedknn( data, vec1, k = 5, weightf = method(:gaussian) ) ... weight = weightf.call( dist ) ... end
你想要一个proc对象:
gaussian = Proc.new do |dist, *args| sigma = args.first || 10.0 ... end def weightedknn(data, vec1, k = 5, weightf = gaussian) ... weight = weightf.call(dist) ... end
请注意,您不能像这样在块声明中设置默认参数.因此,您需要使用splat并在proc代码中设置默认值.
或者,根据您所有这些的范围,可能更容易传递方法名称.
def weightedknn(data, vec1, k = 5, weightf = :gaussian) ... weight = self.send(weightf) ... end
在这种情况下,您只是调用在对象上定义的方法,而不是传递完整的代码块.这取决于你如何组织这个你可能需要更换self.send
与object_that_has_the_these_math_methods.send
最后但并非最不重要的,你可以挂掉方法的块.
def weightedknn(data, vec1, k = 5) ... weight = if block_given? yield(dist) else gaussian.call(dist) end end ... end weightedknn(foo, bar) do |dist| # square the dist dist * dist end
但听起来你想要更多可重复使用的代码块.
您可以通过方式将方法作为参数传递method(:function)
.贝娄一个非常简单的例子:
def double(a) return a * 2 end => nil def method_with_function_as_param( callback, number) callback.call(number) end => nil method_with_function_as_param( method(:double) , 10 ) => 20
正常的Ruby方法是使用块.
所以它会是这样的:
def weightedknn( data, vec1, k = 5 ) foo weight = yield( dist ) foo end
使用如下:
weightenknn( data, vec1 ) { |dist| gaussian( dist ) }
这种模式在Ruby中广泛使用.
您可以&
在Method
方法实例上使用运算符将方法转换为块.
例:
def foo(arg) p arg end def bar(&block) p 'bar' block.call('foo') end bar(&method(:foo))
更多详情,请访问http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html