好的,所以我构建了一个DSL,其中一部分要求DSL的用户定义我称之为“编写器块”的内容
pivot_table()
编写器块被调用如下:
writer do |data_block|
CSV.open("data.csv", "wb") do |csv|
headers_written = false
data_block do |hash|
(csv << headers_written && headers_written = true) unless headers_written
csv << hash.values
end
end
end
这个问题有两个问题,首先,这是处理这类事情的最佳方式,其次是我得到一个奇怪的错误:
def pull_and_store
raise "No writer detected" unless @writer
@writer.call( -> (&block) {
pull(pull_initial,&block)
})
end
奇怪的是,我可以在那里看到undefined method data_block' for Servo_City:Class (NoMethodError)
,或者至少它在data_block
区块之前无论如何都存在。
我尝试创建的是一种让用户编写包装块的方法,该包装块既包裹块又产生块到被包裹的块,哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇/ p>
答案 0 :(得分:1)
内心的我不想在澄清问题之前写一个答案。
其他代码示例的投注将有助于澄清问题。
我假设编写器块的任务是持久保存一些数据。你能以可枚举的形式将数据传递到块中吗?这将允许DSL用户写这样的东西:
writer do |data|
CSV.open("data.csv", "wb") do |csv|
csv << header_row
data.each do |hash|
data_row = hash.values
csv << data_row
end
end
end
无需阻止传递。
请注意,如果处理庞大的数据集,您可以传入 lazy 集合。
这会解决您的问题吗?
答案 1 :(得分:0)
每次要编写记录时,尝试打开CSV文件似乎过于复杂,并且可能导致性能不佳(除非写入是间歇性的)。除非您将文件模式从wb
更改为ab
,否则每次都会覆盖CSV文件。
我觉得很简单:
csv = CSV.open('data.csv', 'wb')
csv << headers
writer do |hash|
csv << hash.values
end
会更容易理解。