Ruby 对象克隆/复制
概述
我正在通过生成 XML 文件的数据库查询在 ruby 脚本中创建对象。我这样做是为了一次只处理一个 XML 文件,并且所有标签都是通用的,因此可以轻松添加其他查询。
问题
我一次创建一个对象,然后将其添加到列表中,如下所示:
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart)
但是每次我处理 XML 文件时都想创建 BarChart,我会重用变量 bar_chart
这导致我的对象的数据被覆盖。我正在寻找解决这个问题的方法。
我尝试过的
我尝试将对象的副本传递到列表中,但这仍然会覆盖数据。
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart.clone)
和
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart.dup)
任何帮助/想法都会很棒。 谢谢。
编辑,更多信息 这是我进行 XML 处理的方法。
def self.process_xml_files2(filenames)
labels = []
data = []
charts = []
title = nil
type = nil
x_axis = nil
y_axis = nil
#retrieve needed data from the XML file
filenames.each do |filename|
f = File.new(filename)
#create a document
doc = Document.new(f)
doc.elements.each("//row/field") do |e|
tag = e.attributes['name']
text = e.text
#search for tags and append correct data to lists
if tag.casecmp('Type') == 0
type = text
elsif tag.casecmp('Title') == 0
title = text
elsif tag.casecmp('Labels') == 0
labels.push(text)
elsif tag.casecmp('Data') == 0
data.push(text)
elsif tag.casecmp('X-Axis') == 0
x_axis = text
elsif tag.casecmp('Y-Axis') == 0
y_axis = text
end
end
f.close()
#test for correct chart parameters
raise "Not Enough Arguments"
if title == nil or type == nil or data.empty? or labels.empty?
#process the raw chart data
if type.casecmp('Bar') == 0
#test for labels
raise "Bar Charts require X and Y axis labels"
if x_axis == nil or y_axis == nil
#format the data for the bar chart
data = BarChart.barify_data(data)
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart)
elsif type.casecmp('Pie') == 0
#format data and labels for the pie chart
data = PieChart.pieify_data(data)
#create a new Pie Chart
pie_chart = PieChart.new(title, data, labels)
#add the pie chart to the chart list
charts.push(pie_chart.clone)
else
raise "Invalid Chart Type: Not Pie or Bar"
end
end
#write all the charts to the images directory
charts.each do |ch|
puts ch.url + "\n\n"
ch.download_image(ch.url, ch.title)
end
end
Overview
I am creating objects in my ruby script from database queries that generates XML files. I have made it so only one XML file is processed at a time and all of the tags are generic so other queries can be added easily.
Problem
I am creating one object at a time, then adding it to a list, like so:
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart)
But every time I process an XML file a want to create a BarChart I am reusing the variable bar_chart
which is causing the data of my objects to be overwritten. I am looking for a way around this.
What I've tried
I have tried to pass a copy of the object into the list, but that is still overwriting the data.
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart.clone)
and
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart.dup)
Any help/ideas would be great.
Thanks.
EDIT, more information
Here is the method I do the XML processing in.
def self.process_xml_files2(filenames)
labels = []
data = []
charts = []
title = nil
type = nil
x_axis = nil
y_axis = nil
#retrieve needed data from the XML file
filenames.each do |filename|
f = File.new(filename)
#create a document
doc = Document.new(f)
doc.elements.each("//row/field") do |e|
tag = e.attributes['name']
text = e.text
#search for tags and append correct data to lists
if tag.casecmp('Type') == 0
type = text
elsif tag.casecmp('Title') == 0
title = text
elsif tag.casecmp('Labels') == 0
labels.push(text)
elsif tag.casecmp('Data') == 0
data.push(text)
elsif tag.casecmp('X-Axis') == 0
x_axis = text
elsif tag.casecmp('Y-Axis') == 0
y_axis = text
end
end
f.close()
#test for correct chart parameters
raise "Not Enough Arguments"
if title == nil or type == nil or data.empty? or labels.empty?
#process the raw chart data
if type.casecmp('Bar') == 0
#test for labels
raise "Bar Charts require X and Y axis labels"
if x_axis == nil or y_axis == nil
#format the data for the bar chart
data = BarChart.barify_data(data)
#create a new BarChart
bar_chart = BarChart.new(title, data, labels, x_axis, y_axis);
#add the chart to the chart list
charts.push(bar_chart)
elsif type.casecmp('Pie') == 0
#format data and labels for the pie chart
data = PieChart.pieify_data(data)
#create a new Pie Chart
pie_chart = PieChart.new(title, data, labels)
#add the pie chart to the chart list
charts.push(pie_chart.clone)
else
raise "Invalid Chart Type: Not Pie or Bar"
end
end
#write all the charts to the images directory
charts.each do |ch|
puts ch.url + "\n\n"
ch.download_image(ch.url, ch.title)
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从我在代码中看到的,您为附加到列表的每个图表重复使用
labels
和data
对象(注意:对象,而不是变量!)。看来您应该将初始化移至
filenames.each
循环内。From what I can see in the code, you are reusing
labels
anddata
objects (be careful: objects, not variables!) for every chart you append to the list. It seems that you should moveinitializations inside the
filenames.each
loop.