我想将方法名称而不是块作为参数传递给另一个用作回调的方法:
def one(param)
puts param
end
def two(param, &callback)
callback.call(param)
end
two('hi', :one)
这可能吗?我试了一下并得到一个错误,说我通过了两个参数但只有一个是预期的。
答案 0 :(得分:3)
如果你想发送一个方法的名称,那么,是的,符号是正确的形式,正如John的答案所指出的那样(然后你可以使用send称这种方法)。但是,如果您愿意,您也可以发送方法本身:
<div id="loginArea">
<div id="searchForm">
Search For Results
<br />
<div>
<form id="search-form" action="/events/search" accept-charset="UTF-8" method="get">
<input name="utf8" type="hidden" value="✓">
<input type="text" name="first_name" id="first_name" placeholder="First Name" class="searchField">
<input type="text" name="last_name" id="last_name" placeholder="Last Name" class="searchField">
<input type="text" name="event" id="event" placeholder="Event" class="searchField">
<input alt="Search" type="image" src="http://www.racertracks.com/assets/magnifying-glass-0220f37269f90a370c3bb60229240f2ef2a4e15b335cd42e64563ba65e4f22e4.png" class="search_button">
</form>
</div>
</div>
</div>
这种做事方式的优点是,当方法需要块时,可以在没有(如def one(param)
puts param
end
def two(param, &callback)
callback.call(param)
end
one_method = method(:one)
two('hi', &one_method)
的情况下)的情况下执行此操作,而无需更改方法定义。你也可以从不同的对象传递方法,而如果你想在另一个对象上调用方法,你也必须传入你想要调用它的人(或以其他方式解决这个问题) ):
two
答案 1 :(得分:2)
您想使用send
:
def two(param, callback)
send(callback, param)
end
答案 2 :(得分:2)
虽然@ JohnNaegle的答案是正确的,但我发现使用#method
会更加优雅地执行此操作,它会返回Method
个对象。方法对象具有.call(*args)
方法,但您可以传递参数。所以,用你的例子看起来像:
def one(param)
puts param
end
def two(param, callback)
callback.call(param)
end
two('hi', method(:one))
更改是您通过调用Method
(与Object.method
相同而不是字符串)传递对method
实例的引用。
如果您想传递符号而不是Method
,则可以使用以下版本的#two
:
def two_2(param, callback)
method(callback.to_sym).call(param)
end
two_2('hi', :one)
# Or you could also pass a string or anything that #responds_to?(:to_sym)
two_2('hi', 'one')
我建议进一步改进,以便two
可以接受多个参数传递给回调,然后首先列出回调,然后使用*params
接收所需数量的参数。以下是一个示例(使用上面#one
的定义):
def one_with_many_params(*params)
puts params.join
end
# Improved version of two
def two_3(callback, *params)
callback.call(params)
end
# Improved version of two_2
def two_4(callback, *params)
method(callback.to_sym).call(params)
end
two_3(method(:one), 'hi') #=> "hi"
two_3(method(:one_with_many_params), "Hi", " my ", "name", " is ", "Foo!")
#=> "Hi my name is Foo!"
two_4('one', 'Hello!') #=> "Hello!"
two_4(:one_with_many_params, "Hi", " my ", "name", " is ", "Bar!")
#=> "Hi my name is Bar!"