Ruby 对象克隆/复制

发布于 2024-11-27 08:50:14 字数 3217 浏览 1 评论 0原文

概述

我正在通过生成 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 技术交流群。

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

发布评论

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

评论(1

内心旳酸楚 2024-12-04 08:50:14

从我在代码中看到的,您为附加到列表的每个图表重复使用 labelsdata 对象(注意:对象,而不是变量!)。看来您应该将

labels = []
data = []

初始化移至 filenames.each 循环内。

From what I can see in the code, you are reusing labels and data objects (be careful: objects, not variables!) for every chart you append to the list. It seems that you should move

labels = []
data = []

initializations inside the filenames.each loop.

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