2011-08-07 43 views
0

这是推动我疯了...以下是我认为我在做什么,我users_controller.rb这些实例变量彼此重写有什么问题?

  1. 我设置会话的#show行动:通过方法“pass_session_data ONLY([ZOT] )”。
  2. 在该方法中,我将“@foo”的内容传递给会话[:zot]。
  3. 在稍后的#show动作中,我将调用amz_search(),然后用URL和文本替换@ nowreading.content中的一些文本。

调用方法“amz_search()”后,所有投注都关闭。当我把“测试4”,我看到会议[:zot]更改为包含我添加到@ nowread.content的URL。更糟的是,当我改变@ nowreading.content时,我的变量@foo也发生了变化。 WTF。我不明白这两个变量是如何联系的!

我在做什么错?我想将未改变的文本(在它更改为带有URL的版本之前的@foo)传递给会话[: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 

谢谢您的帮助。

回答

1

您应该花费30分钟重构该代码 - 尽可能多地删除实例变量,并将明确的参数用于您的函数,而不是对实例变量进行操作。

我敢肯定你的问题是,

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

,然后您在WTF语句之前改变@nowreading

tweet是一个对象,所以当你说@foo=tweet; @nowreading=tweet@foo@nowreading指向同一个对象,修改或者将修改两者。

+0

对于重构来说的确如此。 – whitequark

+0

我会尝试重新分解。但我很困惑,[at] foo == [at]现在的阅读可能是真的!我设置[at] foo的唯一时间是方法parse_the_streams(multi_streams)。奇怪,不是? (@ = [at],否则StackOverflow认为我试图提及一个用户。) – MorningHacker

+0

你设置了两个[at] nowreading_raw和[at] foo等于推文,所以它们都指向相同的对象 – klochner