helper functions permanently altering variables


I'm not sure if I'm maybe not understanding the helper functions
correctly, but I'm having a weird problem that seems like it shouldn't
be. I'm sanitizing some book names for url's using my application

-- application helper

def format_url(url)
    title = url
    truncate(@title, 100, "")
    return title

def clean_string(str)
    str.gsub!(/\W+/, ' ') # all non-word chars to spaces
    str.strip! # ohh la la
    str.downcase! #
    str.gsub!(/\ +/, '-') # spaces to dashes, preferred separator char

-- view showing the books

#returns "a name with a lot of spaces and characters in it"

link_to(image_tag(book.image_url_small), :controller => "book", :action
=> "detail", :book_url => format_url(book.product_name), :key =>

#returns "a-name-with-a-lot-of-spaces-and-characters-in-it"

so the problem is I want a function that formats just the path, but what
I have here alters book.product name permanently, so that when I want to
write it as text to the screen after using format_url,
it-has-the-escape-dashes-everywhere-in-it. how come it alters this when
I pass it as a param, and then variable assign it to "title" and do all
the alterations on the "title" variable?



by the way I notice that the above code is wrong - assume that title and
@title are consistent throughout the function.

The easy answer is that in ruby, everything is an object and objects get
passed by reference, not by value. So when you pass in url to a method,
and then assign it to another variable (title), that new variable is
just a pointer to the same memory location as what was passed in. The
solution is to clone or dup:

Ahhh, ok thanks Phillip! Explanation was good and understood.

I actually solved the problem just recently by doing thus:

title = url + ""

which seems to work and force title not to just remain as a pointer to



Jason Pfeifer wrote:

I actually solved the problem just recently by doing thus:

title = url + ""

And if I had to guess (which I do because I don't feel like digging
through source), I'd say that under the hood the equivalent of

title = url.clone + ""

is happening. So you could save the one or two processor cycles by doing
the clone yourself and not worrying about the concatenation.


Great thanks for the explanation. Processing cycles saved.