如何传递一个闭包来发送Ruby作为参数

时间:2017-05-30 08:24:34

标签: ruby closures send

我像这样使用jQuery(function() { jQuery('.search-checkbox-label').each(function() { jQuery(this).attr('for', jQuery(this).prev('.input-field').attr('id')); }); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form>
  <div class="search-row-location search-row-checkbox-multiple">
    <label for="location" class="search-label">Location</label>
    <div class="field">
      <input checked="" name="location[]" id="location_0" value="0" class="input-field=" type="checkbox">
      <label class="search-checkbox-label">All Locations</label>
      <input name="location[]" id="location_1" value="1" class="input-field" type="checkbox">
      <label class="search-checkbox-label">Sydney</label>
      <input name="location[]" id="location_2" value="1" class="input-field" type="checkbox">
      <label class="search-checkbox-label">Paris</label>
    </div>
  </div>
  <div class="search-row-price search-row-checkbox-multiple">
    <label for="price" class="search-label">Price</label>
    <div class="field">
      <input checked="" name="price[]" id="price_0" value="0" class="input-field=" type="checkbox">
      <label class="search-checkbox-label">All Prices</label>
      <input name="price[]" id="price_1" value="1" class="input-field" type="checkbox">
      <label class="search-checkbox-label">100$</label>
      <input name="price[]" id="price_2" value="1" class="input-field" type="checkbox">
      <label class="search-checkbox-label">200$</label>
    </div>
  </div>
</form>

我试图传递给send索引和rindex的符号,以及执行它们的闭包:

[:last, :first].map { |sym| [0,1,2].send(sym) }
#=> [2, 0]

我收到错误消息:

send

我做错了什么?

3 个答案:

答案 0 :(得分:4)

要传递闭包,应该使用&符号来指示ruby解析器,它是一个块:

[ :rindex, :index ].map do |sym|
  [0,1,2].send(sym, &->(x){ x % 2 == 0  })
end
#⇒ [2, 0]

答案 1 :(得分:2)

没有火箭科学选择:

%i(rindex index).map { |meth| [0,1,2].public_send(meth) { |x| x % 2 == 0  } }
#=> [2, 0]

稍短(使用Integer#even?):

%i(rindex index).map { |meth| [0,1,2].public_send(meth, &:even?) }
#=> [2, 0]

答案 2 :(得分:1)

  

我做错了什么?

在Ruby中,在参数列表之后传递块而不是中的

foo(1, { puts 'Hello' }) # wrong
foo(1) { puts 'Hello' }  # right

因此,您的代码应如下所示:

[:rindex, :index].map {|sym| [0, 1, 2].send(sym) {|x| x %2 == 0 }}

注意:您应该始终优先public_send而不是sendsend一次做两件事:允许消息的名称是动态的,并打破封装。如果您使用send,那么阅读您的代码的人永远不会确定您实际使用的这两个功能中的哪一个。在这种情况下,您根本不打破封装,只使用动态消息名称。这正是public_send所做的。

%i[rindex index].map {|meth| [0, 1, 2].public_send(meth, &:even?)}

这是编写代码的更惯用的方式。