这些实例变量互相重写有什么问题吗?
这让我发疯......这就是我认为我在 users_controller.rb 的 #show 操作中所做的事情,
- 我仅通过方法“pass_session_data()”设置会话[:zot]。
- 在该方法中,我将“@foo”的内容传递给会话[:zot]。
- 稍后在 #show 操作中,我调用 amz_search(),并将 @nowreading.content 中的一些文本替换为 URL 和该文本。
调用“amz_search()”方法后,所有的赌注都消失了。当我输入“test 4”时,我看到 session[:zot] 已更改为包含我添加到 @nowreading.content 的 URL。更糟糕的是,当我更改@nowreading.content 时,我的变量@foo 也发生了更改。 WTF。我不明白这两个变量是如何联系起来的!
我做错了什么?我想将未更改的文本(@foo 在更改为带有 URL 的版本之前)传递给 session[:zot]。
在用户控制器的显示操作中,我有:
@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
以下是显示操作调用的方法:
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
谢谢您的帮助。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该花 30 分钟重构该代码 - 消除尽可能多的实例变量,并对函数使用显式参数,而不是对实例变量进行操作。
我很确定你的问题是
然后你在你的WTF语句之前更改
@nowreading
。tweet
是一个对象,所以当你说@foo=tweet; @nowreading=tweet
、@foo
和@nowreading
指向同一个对象,修改其中任何一个都会同时修改两者。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
@nowreading
right before your WTF statement.tweet
is an object, so when you say@foo=tweet; @nowreading=tweet
,@foo
and@nowreading
point to the same object, and modifying either will modify both.