Ruby 默认块和收益
Ruby default block and yield
我正在解决以下问题:
describe "some silly block functions" do
describe "reverser" do
it "reverses the string returned by the default block" do
result = reverser do
"hello"
end
expect(result).to eq("olleh")
end
根据我的理解,这应该反转一个字符串。我的代码如下:
def reverser
yield "hello"
end
reverser do |i|
puts i.reverse
end
这简直returns"hello"。我可能在这里遗漏了一些关于 yield、blocks 和 functions 如何相互作用的基本概念。我该如何去做我想完成的事情?
您需要在reverser
中包含反转字符串的逻辑。
def reverser
yield.reverse
end
但为什么还要费心使用块呢?用普通参数就清楚多了
def reverser(str)
str.reverse
end
reverser('hello') #=> olleh
如果要将要反转的字符串放入block中,则需要获取调用block的结果并进行反转。
def reverser(&block)
block.call.reverse
end
irb(main):009:0> result = reverser do
irb(main):010:1* "hello"
irb(main):011:1> end
=> "olleh"
答案很好而且正确,但也许仍然无济于事。
您应该从您的规格开始:
it "reverses the string returned by the default block"
那么,你的方法应该做什么就很清楚了:
def reverser
# should reverse the string returned by the default block
end
现在让我们看看如何实现它。好的,它应该扭转一些事情。但是什么?让我们看看:
string returned by the default block
这表明我们需要执行默认块并获取其 returned 值。让我们看看 docs 怎么说:
yield
- Called from inside a method body, yields control to the code block (if any) supplied as part of the method call. ... The value of a call to yield is the value of the executed code block.
所以,看来你的方法需要执行一次yield
。它将执行一个块和 return 块的值 returns。所以,只需在此处放一个 yield
。
def reverser
yield
end
如果你 运行 你的规范,它会抱怨 - 你会看到字符串仍然没有反转。所以,这就是您的方法要做的事情:
def reverser
yield.reverse
end
就是这样。
我同意以上回复 - 它们最有道理。但想补充说明您的代码无法正常工作的原因以及解决方法:
expect(result).to eq("olleh")
所以根据你想要的结果 return 一个字符串。是这样做的吗?
- 将return设为零。当您将 put 放在方法的末尾时 - 请注意该方法将为 return nil。这是阴险的,因为有时结果不是预期的。
- 但你期望它 return 'olleh'
- 摆脱看跌期权,它应该像你期望的那样工作(未经测试)
def reverser
yield "hello"
end
reverser do |i|
i.reverse # NOTE THAT THE PUTS is missing here
end
我想这就是您要找的。
编辑:请测试并告诉我,因为有些人认为我的答案完全错误!当然你不想依赖你正在使用的特定块作为设计点,但这应该让你知道为什么它不起作用
我知道已经过去一年了,但还没有得到正确的回答。
def reverser
out = []
yield.split.each{|word| out << word.reverse}
out.join(" ")
end
我很确定它与范围有关
我正在解决以下问题:
describe "some silly block functions" do
describe "reverser" do
it "reverses the string returned by the default block" do
result = reverser do
"hello"
end
expect(result).to eq("olleh")
end
根据我的理解,这应该反转一个字符串。我的代码如下:
def reverser
yield "hello"
end
reverser do |i|
puts i.reverse
end
这简直returns"hello"。我可能在这里遗漏了一些关于 yield、blocks 和 functions 如何相互作用的基本概念。我该如何去做我想完成的事情?
您需要在reverser
中包含反转字符串的逻辑。
def reverser
yield.reverse
end
但为什么还要费心使用块呢?用普通参数就清楚多了
def reverser(str)
str.reverse
end
reverser('hello') #=> olleh
如果要将要反转的字符串放入block中,则需要获取调用block的结果并进行反转。
def reverser(&block)
block.call.reverse
end
irb(main):009:0> result = reverser do
irb(main):010:1* "hello"
irb(main):011:1> end
=> "olleh"
答案很好而且正确,但也许仍然无济于事。
您应该从您的规格开始:
it "reverses the string returned by the default block"
那么,你的方法应该做什么就很清楚了:
def reverser
# should reverse the string returned by the default block
end
现在让我们看看如何实现它。好的,它应该扭转一些事情。但是什么?让我们看看:
string returned by the default block
这表明我们需要执行默认块并获取其 returned 值。让我们看看 docs 怎么说:
yield
- Called from inside a method body, yields control to the code block (if any) supplied as part of the method call. ... The value of a call to yield is the value of the executed code block.
所以,看来你的方法需要执行一次yield
。它将执行一个块和 return 块的值 returns。所以,只需在此处放一个 yield
。
def reverser
yield
end
如果你 运行 你的规范,它会抱怨 - 你会看到字符串仍然没有反转。所以,这就是您的方法要做的事情:
def reverser
yield.reverse
end
就是这样。
我同意以上回复 - 它们最有道理。但想补充说明您的代码无法正常工作的原因以及解决方法:
expect(result).to eq("olleh")
所以根据你想要的结果 return 一个字符串。是这样做的吗?
- 将return设为零。当您将 put 放在方法的末尾时 - 请注意该方法将为 return nil。这是阴险的,因为有时结果不是预期的。
- 但你期望它 return 'olleh'
- 摆脱看跌期权,它应该像你期望的那样工作(未经测试)
def reverser yield "hello" end reverser do |i| i.reverse # NOTE THAT THE PUTS is missing here end
我想这就是您要找的。
编辑:请测试并告诉我,因为有些人认为我的答案完全错误!当然你不想依赖你正在使用的特定块作为设计点,但这应该让你知道为什么它不起作用
我知道已经过去一年了,但还没有得到正确的回答。
def reverser
out = []
yield.split.each{|word| out << word.reverse}
out.join(" ")
end
我很确定它与范围有关