This is driving me crazy… Here’s what I THINK I’m doing in the #show action of my users_controller.rb
- I’m setting session[:zot] ONLY via the method “pass_session_data()”.
- In that method, I pass the contents of “@foo” to the session[:zot].
- Later in the #show action, I call amz_search(), and I replace some text in @nowreading.content with the a URL and that text.
After the calling the method “amz_search()” all bets are off. When I put “test 4”, I see the session[:zot] changed to include the URL that I added to @nowreading.content. Worse still, my variable @foo also changed when I changed @nowreading.content. WTF. I don’t understand how these two variables are linked!
What am I doing wrong? I want to pass the unaltered text (@foo before it changes to the version with the URL) to session[:zot].
In the show action of the Users controller, I have:
@user = User.find(params[:id])
@nowpost = Nowpost.new
@tweet_sample = Micropost.find(:all, :conditions => ["username = ?", "#{@user.twithandle}"])
@multi_streams = (@tweet_sample + @user.nowposts).sort_by(&:updated_at)
# takes all posts in the systems and order them by update-time
parse_the_streams(@multi_streams)
pass_session_data()
puts "test 3"
puts session[:zot]
puts "this is @foo = #{@foo.content}"
puts "Test C = #{@nowreading_raw.content}"
amz_search(@reading_title, 'Books')
puts "test 4"
puts session[:zot]
puts "this is @foo = #{@foo.content}"
# @foo totally changed even though I only updated @nowpost.content
# I don't understand how these two variables are linked!
puts "Test D = #{@nowreading_raw.content}"
end #show action
Here are the methods call from the show action:
def parse_the_streams(multi_streams)
multi_streams.each do |tweet, i|
puts "i = #{i} // tweet = #{tweet.content}"
if tweet.content.match(/#nowreading/).to_s == "#nowreading"
@nowreading_raw = tweet
@foo = tweet
tweet.update_attributes(:cat_id => "1")
if tweet.content.match(/#nowreading$/)
@reading_title = tweet.content.match(/([^\s]*\s){5}(#nowreading$)/).to_s
else
@reading_title = tweet.content.match(/'(.+)'|"(.+)"/).to_s
end
end
end
end
def pass_session_data
@nowreading = @nowreading_raw
puts "PASS SESSION DATA"
puts "this is @foo = #{@foo.content}"
puts "----------"
reading = @foo
content = {
"reading"=>reading
}
session[:zot] = content
end
def amz_search(search, index)
res = Amazon::Ecs.item_search(search, {:response_group => 'Images', :search_index => index})
puts "Test 1 = #{session[:zot]["reading"].content}"
tempy = @nowreading.content.match(/#nowreading.*/).to_s.gsub("#nowreading",'') # strips away the #nowreading tag
puts "Test 2 = #{session[:zot]["reading"].content} -- this is still OK"
puts "and FOO hasn't changed yet = #{@foo.content}"
url = create_amz_url(search, asin)["finished"]
@nowreading.content = tempy.match(/#{search}.*/).to_s.gsub("#{search}", url)
puts "WTF -- @foo changed -- WHY!?!? = #{@foo.content}"
puts "Test 4 = #{session[:zot]["reading"].content}"
end
def create_amz_url(text, asin)
url = Hash.new
url["raw"] = "http://www.amazon.com/dp/#{asin}/#{associate_code}"
link = "http://www.amazon.com/dp/#{asin}/#{associate_code}"
url["finished"] = "<a href=#{link} target=\"_blank\">#{text}</a>"
return url
end
Thank you for your help.
You should spend 30 minutes refactoring that code – eliminate as many instance variables as possible and use explicit arguments to your functions rather than operating on the instance variables.
I’m pretty sure your problem is that
and then you change
@nowreadingright before your WTF statement.tweetis an object, so when you say@foo=tweet; @nowreading=tweet,@fooand@nowreadingpoint to the same object, and modifying either will modify both.