【发布时间】:2017-03-05 18:41:19
【问题描述】:
好的,所以我已经构建了一个 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
编写器块被这样调用:
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 块之前。
我正在尝试创建的是一种让用户编写包装块的方法,该包装块既可以环绕一个块,又可以为被包装的块生成一个块,哇,真是一口。
【问题讨论】:
-
嗯,我不太明白你想要完成什么。有多种可能的失败原因,其中一些可能在您未显示的代码中。只是一个有根据的猜测:您调用
writer的块接受一个块data_block反过来又接受一个块。对于 DSL 来说似乎非常复杂。尝试像这样取消引用它:writer do |&data_block|,然后使用data_block.call do |hash|调用它。我没有看到hash被传入的位置。(pull会这样做吗?)你为什么不首先像writer do |data_block, hash|那样将它传递给 writer 块? -
这就是我问的原因,它有点复杂。
pull接收一个块并为其生成一个哈希值;因此@writter.call需要一个块,该块是传递给data_block的块。我这样做的原因是我能想到的唯一方法是让我将pull方法包装在CSV块内。否则我必须创建一个 csv 对象,将散列附加到 csv 文件,然后为每个产生的散列关闭它。我觉得我过于复杂了,我可以传递一个 IO 对象或其他东西并使用它吗?
标签: ruby ruby-block