Helper functions permanently altering variables

Greetings,

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
helper:

– application helper

def format_url(url)
title = url
clean_string(title)
truncate(@title, 100, “”)
return title
end

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
everywhere
end

– view showing the books

book.product_name
#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 =>
book.isbn)

book.product_name
#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?

Thanks,

Jason

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

Jason P. wrote:

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:

title = url.clone

And you should be okay. I may have over-simplified the explanation, and
if so, someone else might elect to explain it better.

Peace,
Phillip

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
url.

Cheers,

Jason

Jason P. 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.

Peace,
Phillip

Great thanks for the explanation. Processing cycles saved.