0

好的,所以我已经构建了一个 DSL,其中一部分需要 DSL 的用户定义我所说的“编写器块”

  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

writer 块的调用方式如下:

  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在那里看到,或者至少它至少存在于CSV街区之前。

我正在尝试创建的是一种让用户编写包装块的方法,该包装块既环绕一个块,又为被包装的块产生一个块,哇,这真是一口。

4

2 回答 2

1

在问题被澄清之前,内在的我不想写答案。
其他我打赌代码示例将有助于澄清问题。


我假设 writer 块具有持久化一些数据的任务。你能以可枚举的形式将数据传递到块中吗?这将允许 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

不需要块传递。

请注意,如果处理巨大的数据集,您可以传入惰性集合。

这能解决你的问题吗?

于 2017-03-06T20:45:23.927 回答
0

每次要写入记录时都尝试打开 CSV 文件似乎过于复杂,并且可能导致性能不佳(除非写入是间歇性的)。wb除非您将文件模式从更改为 ,否则它每次都会覆盖 CSV 文件ab

我认为一些简单的事情是:

csv = CSV.open('data.csv', 'wb')
csv << headers
writer do |hash|
  csv << hash.values
end

会更容易理解。

于 2017-03-07T06:21:07.183 回答