在Ruby中,我正在解析CSV文件并将值存储到类中(csv中的每个“列”对应于我的类的属性,Expense)。我的CSV有15.000行。但是在我浏览完所有行之后,我只有260个Expense类对象,而不是15.000,这是行数。如果我解析一个包含100行的CSV,它可以正常工作,它会创建100个Expense类对象。但是从150行开始创建问题 - 150行返回36个类Expense的实例,15.000返回260.我没有看到逻辑,就像在某些时候它重置了我的类的实例数并重新开始计数。
一个类在Ruby中可以拥有的实例数量是否有限制?
这不是一个程序,我是一个真正的打手。我只是通过CSV,对数据进行一些验证,然后返回到CSV。所以我一直在寻找一种方法,我不需要将值存储在临时文件中。
由于
代码:
class Expense
attr_accessor :var1, :var2, :var3
def initialize(var1,var2,var3)
@var1 = var1
@var2 = var2
@var3 = var3
end
def self.count
ObjectSpace.each_object(self).to_a.count
end
end
old_file = File.read("C:/Folder/OldFile.csv")
new_file = File.new("C:/Folder/NewFile.csv", "w")
puts "Number of rows in input file: #{old_file.count("\n")}"
puts "Number of Expense objects stored before procedure: #{Expense.count}"
#loop through the rows and store each column as an attribute of the class
old_file.each_line do |line|
#save each column of the row as an element of the array
attr_ay = []
line.chomp.each_line(';') do |att|
attr_ay.push(att.chomp(";"))
end
#loops through each attribute and assigns the corresponding value of the array
i=0
expense = Expense.new("","","")
expense.instance_variables.each do |att|
expense.instance_variable_set(att,attr_ay[i])
new_file.print(expense.instance_variable_get(att)+";")
i = i + 1
end
#jump to the next line in new file
new_file.print "\n"
end
new_file.close
#compare number of rows
new_file = File.read("C:/Folder/NewFile.csv")
puts "Number of rows in output file: #{new_file.count("\n")}"
puts "Number of Expense objects stored after procedure: #{Expense.count}"
#Result:
#Number of rows in input file: 15031
#Number of Expense objects stored before procedure: 0
#Number of rows in output file: 15031
#Number of Expense objects stored after procedure: 57
答案 0 :(得分:2)
这个答案基于我和Max的评论似乎解决了这个问题。
问题中的代码不受对象数量限制的影响。 Ruby语言没有固有的限制,大多数实现允许大量的对象,超过数TB的内存。脚本通常在用完对象指针之前耗尽内存或CPU时间。
使用ObjectSpace
访问对象是导致问题的原因:
ObjectSpace
是一个有用的调试工具或元编程工具,您可以使用它找到当前对象,但它不维护任何活动引用。 修复方法是使用容器来保存对象。只需push
- 将它们打开到Array
即可创建必要的引用,并阻止垃圾回收对您来说是一个问题。您应该使用该变量来查找和计算对象,而不是ObjectSpace
。