首页 > 解决方案 > 为什么我的副本也会影响原件?

问题描述

我正在尝试通过一些修改将副本添加到数组中:

  site.pages.dup.each do | page |
    new_page = page.dup
    data = new_page.data
    data['permalink'] = File.join('/app', page.url)
    data['layout'] = 'app'
    site.pages << new_page
  end

  site.pages.each do | page |
    puts page.data
  end 

当我输出 page.data 时,永久链接是不同的,但data['layout']对于数组中的所有项目都是相同的。我还尝试了 data =并在每个实例中new_page.data.dup写出。new_page.data

标签: ruby-on-railsrubyruby-on-rails-3

解决方案


(移动评论以回答格式化。)

请提供数据示例;我在使用类似结构时遇到零问题,例如,

pages = [
  {
    'name' => 'page 1',
    'data' => {
      'permalink' => 'p1 perma',
      'layout'    => 'p1 layout'
    }
  },

  {
    'name' => 'page 2',
    'data' => {
      'permalink' => 'p2 perma',
      'layout'    => 'p2 layout'
    }
  },
]

如果我(基本上)使用您的代码,加上我的评论:

pages.dup.each do |p|
  new_page = p.dup

  new_data = new_page['data'].dup

  new_data['layout']    = 'app'
  new_data['permalink'] = "#{new_data['permalink']} whatever"

  new_page['data'] = new_data

  pages << new_page
end

我得到以下输出:

[{"name"=>"page 1", "data"=>{"permalink"=>"p1 perma", "layout"=>"p1 layout"}},
 {"name"=>"page 2", "data"=>{"permalink"=>"p2 perma", "layout"=>"p2 layout"}},
 {"name"=>"page 1", "data"=>{"permalink"=>"p1 perma whatever", "layout"=>"app"}},
 {"name"=>"page 2", "data"=>{"permalink"=>"p2 perma whatever", "layout"=>"app"}}]

不相关,但我会将数组串联分开;相反,请考虑map对页面执行 ping 操作,并使用原始数组pages和修改后的数组创建一个新数组。现在你正在做一个dup不必要的额外工作,它增加了一些混乱。

我还将data复制/修改分解为一个单独的方法(可能是整个复制过程)以真正保持紧密,大致:

def modify_page_data(data)
  new_data = data.dup

  new_data['permalink'] = "#{data['permalink']} whatever"
  new_data['layout'] = 'app'

  new_data
end

def dup_page(page)
  new_page = page.dup
  new_page['data'] = modify_page_data(page['data'])
  new_page
end

new_pages = pages.map(&method(:dup_page))

然后你可以concat或任何你想要的原始pages页面和修改后的新页面。

https://github.com/davelnewton/stackoverflow/tree/master/ruby/51289405


推荐阅读