I am working on the following problem:
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
From my understanding this should reverse a string. My code is as follows:
def reverser
yield "hello"
end
reverser do |i|
puts i.reverse
end
This simply returns "hello". I may be missing some fundamental concepts here about how yield, blocks, and functions all interact. How do I going about doing what I am trying to accomplish?
The answers are good and correct but perhaps it still do not help.
You should start with your spec:
it "reverses the string returned by the default block"
So, it's very clear what your method should do:
def reverser
# should reverse the string returned by the default block
end
Let's now see how to achieve it. Ok, it should reverse something. But what? Let's see:
string returned by the default block
This suggests that we need to execute the default block and get its returned value. Let's see what the docs say:
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.
So, it seems that your method needs to perform a yield
. It will execute a block and return the value the block returns. So, just put a yield
there.
def reverser
yield
end
If you run your spec, it will complain - you will see that the string is still not reversed. So, that's whats left for your method to do:
def reverser
yield.reverse
end
and that's it.
You need to include the logic of reversing the string in reverser
.
def reverser
yield.reverse
end
But why bothering using block anyway? It's much clearer to use a normal parameter.
def reverser(str)
str.reverse
end
reverser('hello') #=> olleh
If you want to put the string to reverse in the block, then you need to get the result of calling the block and reverse it.
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"
I know it's been a year but this hasn't been answered right.
def reverser
out = []
yield.split.each{|word| out << word.reverse}
out.join(" ")
end
I'm pretty sure it has to do with scope
I agree with the above responses - they make the most sense. but want to add why your code isn't working and how to fix it:
expect(result).to eq("olleh")
So according to that you want result to return a string. Is it doing that?
def reverser yield "hello" end reverser do |i| i.reverse # NOTE THAT THE PUTS is missing here end
I think that's what you are looking for.
edit: Please test and let me know because some folks think I have the answer completely wrong! of course you'd not want to rely on the particular block that you are using as a design point, but this should give you an idea of why it wasn't working
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.