【问题标题】:Explicitly yielding n values to Symbol#to_proc向 Symbol#to_proc 显式生成 n 个值
【发布时间】:2012-01-26 03:02:13
【问题描述】:

discovered tonight Ruby 的Symbol#to_proc 处理超出第一个产生的值作为方法调用的参数。也就是说,这两个方法调用是等价的:

yields_three{ |a,b,c| a.foo(b,c) }
yields_three( &:foo )

我认为这可能是一个强大(或至少有趣)的成语探索,所以我尝试了以下方法:

class Player
  def add_score( points )
    @score += points
  end
end

my_array_of_players.zip( my_array_of_turn_scores ).each(&:add_score)

很遗憾,这不起作用:

NoMethodError: undefined method `add_score' for [<#Player 'Phrogz'>, 42]:Array

那么,问题来了:你能写一个Enumerator#explicitly 方法,而不是产生一个单一的值数组,而是显式地产生所有这些值吗?

如果你成功了,这些应该会起作用:

pairs = [[1,2],[3,4],[5,6]]
pairs.map.explicitly(&:+) #=> [3,7,11]
pairs.map.explicitly(&:*) #=> [2,12,30]

class String
  def say_hey(b)
    puts "#{self} says 'hey' to #{b}"
  end
end
('a'..'d').each_cons(2).explicitly(&:say_hey)
#=> "a says 'hey' to b"
#=> "b says 'hey' to c"
#=> "c says 'hey' to d"

【问题讨论】:

  • 也许你可以参考提出这个问题的问题。我一直想知道为什么enumerable.inject(&amp;:method) 有效,现在它是有道理的。

标签: ruby


【解决方案1】:

你可以这样做:

class Enumerator
  def explicitly
    each { |e| yield(*e) }
  end
end

我对此执行了您的测试,并返回了正确的结果。

更新:更改为不显式捕获块。

【讨论】:

  • 不错的一个! @tokland 的简短回答也使速度提高了 10%。现在的问题是,这个的好名字是什么? explicitly? splatted?
  • 是的,当然,我不应该明确捕获该块,因为我没有将它传递到其他任何地方。 yield 在这里表现更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 2017-05-08
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多