require 'rubygems'
require 'activesupport'
# this doesn't work as expected. does anyone know why?
z = returning html="" do
html += "stuff"
html += "more stuff" if true
end
p z
#>> ""
# this works though
z = returning html=[] do
html << "stuff"
html << "more_stuff" if true
end.join("\n")
p z
#>> "stuff\nmore_stuff"
Update: Thanks DrMark, I should have done it like this:
(I didn’t realize that one could use << on strings)
z = returning html="" do
html << "stuff"
html << " more stuff" if true
end
5 Responses to “returning doesn't work with empty/blank string??”
Sorry, comments are closed for this article.

September 30th, 2008 at 05:50 PM
There are a couple of things going on here. The second case works because you are using the << method. This changes the original array even though you are inside the block. For the string case, you are confusing variable scopes. If you want to use the "html=''" syntax, you need to use this inside your block:
z = returning html="" do html << "stuff" html << "more stuff" if true end
which will change the original string or more similar to your first attempt:
z = returning html do html += "stuff" html += "more stuff" if true end
notice I did not use "html=''" in this approach, I simply return the inner variable.
Best of luck, DrMark
October 10th, 2008 at 12:35 AM
You should yield to the block.Your examples piggy back on scope outside the block - returning in your first example essentially ignores the scope inside the block ...
See http://gist.github.com/15951 for correct and reliable use.
October 10th, 2008 at 05:55 AM
str = "abc" firstid = str.objectid str += "def" secondid = str.objectid str << "ghi" thirdid = str.objectid
puts firstid == secondid
=> false
puts secondid == thirdid
=> true
October 10th, 2008 at 05:00 PM
"returning" is a red herring. Consider:
x = y = 5 y = 6 p x
Do you expect 5 or 6? x is 5 because x = y = 6 is really x = (y = 5) and y = 5 returns the value 5, not a some kind of magic reference to the variable y that updates when y updates.
Your second example is this:
x = y = [3, 2, 1] y = y.sort p x
Now x is a reference to the original array, and it is not sorted because y.sort created a sorted copy of the array and that doesn't change x. So x is still [3, 2, 1]
x = y = [3, 2, 1] y.sort! p x
This time sort! destructively modifies the original array, so x becomes [1, 2, 3].
As for returning, I would never write returning (html = ...). I usually write:
returning(somevalueexpression) do |variable| ... end
It is up to you to make sure that whatever you do in the block destructively modifies somevalueexpression. For example, Array#uniq! is a handy method, but quite annoyingly, it returns nil if no changes are made. So:
returning(somearrayexpression) do |arr| arr.uniq!; end
This always returns the array, just like #uniq, but doesn't create a copy and never returns nil.
October 10th, 2008 at 06:02 PM
Thanks everyone for the helpful comments!
@Laurent, your snippets are functionally identical to mine, and the first one still doesn't work. The final solution for me is to use the << operator on the string instead of +=