这些实例变量互相重写有什么问题吗?

发布于 2024-11-28 17:32:03 字数 3260 浏览 0 评论 0原文

这让我发疯......这就是我认为我在 users_controller.rb 的 #show 操作中所做的事情,

  1. 我仅通过方法“pass_session_data()”设置会话[:zot]。
  2. 在该方法中,我将“@foo”的内容传递给会话[:zot]。
  3. 稍后在 #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

  1. I'm setting session[:zot] ONLY via the method "pass_session_data()".
  2. In that method, I pass the contents of "@foo" to the session[:zot].
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葬心 2024-12-05 17:32:03

您应该花 30 分钟重构该代码 - 消除尽可能多的实例变量,并对函数使用显式参数,而不是对实例变量进行操作。

我很确定你的问题是

@foo == @nowreading == @nowreading_raw
session[:zot] = {"reading" => @foo}

然后你在你的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

@foo == @nowreading == @nowreading_raw
session[:zot] = {"reading" => @foo}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文