我在ruby中理解Blocks vs Procs时遇到了麻烦。我得到一个基本的想法,即proc是一个保存为对象的方法,你可以反复调用,而不必一遍又一遍地继续编写相同的代码行。
我的麻烦在于接受块作为方法中的参数。
家庭作业问题非常简单。
编写一个接受块作为参数的方法,并反转字符串中的所有单词。
以下是他们正在寻找的答案。
def reverser(&prc)
sentence = prc.call
words = sentence.split(" ")
words.map { |word| word.reverse }.join(" ")
end
我有两个问题 -
1 如何调用此方法,因为如果我放
print reverser("Hello")
我收到错误"错误的参数数量(给定1,预期为0)"
其次,为什么不写下面的方法呢?编写一个阻塞方法的好处是什么?
def reverser(string)
string.split.map{|x| x.reverse}.join(" ")
end
答案 0 :(得分:6)
你这样称呼它:
print reverser { "Hello" }
或者如果您的区块长了几行,那么就像这样:
print reverser do
"Hello"
end
地图就是一个很好的例子。 根据您需要的规则,映射需要一个数组并映射(转换)每个元素。
这些映射规则必须是代码。这意味着,它不能是字符串或数字或其他东西,它必须是一个函数。这里使用块作为函数,您可以使用最少的代码编写。
所以在你的例子中你有这个:
words.map { |word| word.reverse }.join(" ")
如果你无法将块传递给map,那么你必须定义该函数并将其传递到某个地方 - 并命名该函数。那效率不高。
让我们更改此块以使其仅在以大写字母开头时才会反转单词。
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)