【问题标题】:What is the difference between passing a block as an argument and passing a proc as a argument?将块作为参数传递和将 proc 作为参数传递有什么区别?
【发布时间】:2023-03-23 12:25:01
【问题描述】:

我们必须编写一个函数,该函数应该接受一个数组、一个过程和一个块作为参数。它应该返回数组中传递到块时结果最大的元素。如果是平局,它应该使用 proc 来打破平局。

解决方法如下:

def max_tie_breaker(array, tie_breaker, &prc)
    return nil if array.empty?
    max = array.first
    array.each do |el|
        result_el = prc.call(el)
        result_max = prc.call(max)
        if result_el > result_max
            max = el
        elsif result_el == result_max && tie_breaker.call(el) > tie_breaker.call(max)
            max = el
        end
    end
    max
end

在测试代码时,他们做了以下事情:

array_1 =['potato', 'swimming', 'cat'] 
array_2 = ['cat', 'bootcamp', 'swimming', 'ooooo']
array_3 = ['photo','bottle', 'bother'] 
length = Proc.new { |s| s.length } 
o_count = Proc.new { |s| s.count('o') }

        

print max_tie_breaker(array_1, o_count, &length)
#('swimming')
puts
print max_tie_breaker(array_2, length, &o_count)
#('ooooo')
puts

我不明白的是,如果他们将块和 proc 作为参数传递,那么块将在方法参数中显示为 &prc,将在调用方法时通过传入块来调用。例如调用 max_tie_breaker,你不会输入: max_tie_breaker(array_1, o_count) { |s| s.length } 而不是 max_tie_breaker(array_1, o_count, &length)。基本上,我不明白他们如何有一个方法需要一个数组、一个块和一个 proc 作为参数,但是用一个数组和两个 proc 调用它,它仍然可以正常工作。

提前感谢您的帮助或指导。

【问题讨论】:

  • 无论如何我都不是红宝石专家,所以其他人可能会纠正我。您注意到的上述行为是:由于 ruby​​ 约定。当您拥有&prc 时,这会将块转换为过程。但是,如果您将 proc 作为第三个参数传递,它仍然可以工作。

标签: ruby block proc


【解决方案1】:

& 运算符尝试将后面的任何内容转换为块。

因此,当您使用 foo(a, &b) 调用方法时,该方法不会接收 2 个参数,该方法会接收 a 作为它的第一个也是唯一的参数,并且还会给定一个块。

方法可以通过使用yield 关键字来调用块,或者再次使用& 运算符将它们变成可调用的过程。

例如def foo(a, &b) 可以称为foo(a, &b)foo(a) { "bar" }。在这两种情况下,b 方法内部都会有一个代表给定块的 proc。

使用 2 个 proc 而不是一个 proc 和一个块调用此方法会出错。

def foo(a, &b)
end

foo(->{}, ->{}) # ArgumentError: wrong number of arguments (given 2, expected 1)
foo(->{}, &->{}) # nil
foo(->{}) {} # nil
foo(->{}) do end # nil

【讨论】:

  • 谢谢。这是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多