Ruby - 为什么使用块作为参数?

Ruby - Why use a Block as a parameter?

我无法理解 ruby 中的块与过程。我的基本想法是 proc 是一种保存为对象的方法,您可以重复调用该对象,而不必一遍又一遍地继续编写相同的代码行。

我的问题在于接受块作为方法中的参数。

作业题超级简单。

编写一个方法,接受一个块作为参数并反转字符串中的所有单词。

以下是他们正在寻找的答案。

def reverser(&prc)
  sentence = prc.call
  words = sentence.split(" ")
  words.map { |word| word.reverse }.join(" ")
end

我有两个问题 -

1 你怎么调用这个方法因为如果我把

print reverser("Hello") 

我得到一个错误 "wrong number of arguments (given 1, expected 0)"

其次,为什么不直接写下面的方法呢?编写一个带块的方法有什么好处?

def reverser(string)
  string.split.map{|x| x.reverse}.join(" ")
end 
  1. 你可以这样称呼它:

    print reverser { "Hello" }
    

或者,如果您的块有几行那么长,那么像这样:

print reverser do
  "Hello"
end
  1. 块接近于其他语言中的匿名函数。

地图就是一个很好的例子。 map 的作用是获取一个数组并根据您需要的任何规则映射(转换)每个元素。

这些映射规则必须是代码。这意味着,它不能是字符串或数字或其他东西,它必须是一个函数。 Block 在这里用作函数,您可以使用最少的代码编写它。

所以在你的例子中你有这个:

words.map { |word| word.reverse }.join(" ")

如果您不能将块传递给映射,那么您必须定义该函数并将其传递到某处 - 并命名该函数。那就是效率不高。

让我们更改此块以使其仅在以大写字母开头时才反转单词。

words.map do |word| 
  if word[0] =~ /[A-Z]/ 
    word.reverse
  else
    word
end.join(" ")

如果没有块,您需要定义该函数,您在任何其他地方都不需要它并调用它。那是没有效率的。 这就是它的样子

def reverse_if_starts_with_capital_letter(word)
  if word[0] =~ /[A-Z]/ 
    word.reverse
  else
    word
  end
end

# not sure if this syntax would work, just demonstrates idea
words.map(&reverse_if_starts_with_capital_letter)