2017-03-05 15 views
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 

作家塊被稱爲像這樣:

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區塊之前。

我想要創建的是一種讓用戶編寫一個封裝塊的方法,該封裝塊既可以環繞一個塊,又可以產生一個被包裹的塊​​,哇,這是一口。

+0

嗯,我真的不明白你想要完成什麼。有多種可能的失敗原因,有些可能在你沒有顯示的代碼中。只是一個受過教育的猜測:你用一個接受block'data_block'的塊調用'writer',它接受一個塊。似乎DSL非常複雜。嘗試解除引用,像這樣:'writer do |&data_block |',然後用'data_block.call do | hash |'調用它。我沒看到的是'hash'被傳入的地方。(拉'是否這樣做?)爲什麼你不會首先將它傳遞給writer模塊,比如'writer do | data_block,hash |'' ? – Raffael

+0

這就是爲什麼我問,這有點複雜。 'pull'接受一個塊併產生一個散列值;因此'@ writter.call'需要一個塊,它是傳遞給'data_block'的塊。我這樣做是因爲這是我可以考慮的唯一方法,允許我在'CSV'塊中包裝'pull'方法。否則,我必須創建一個csv對象,將散列追加到csv文件,然後關閉每個散列產生的散列。我覺得我太過於複雜,我可能會傳遞一個IO對象或東西,並使用它呢? – Thermatix

回答

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 

沒有阻止通過要求。

請注意,如果處理巨大的數據集,您可以傳入懶惰集合。

這是否解決您的問題?

+0

對不起,直到現在還沒有響應,'data.each'不會工作,因爲它不會產生迭代器,而是調用塊並將散列傳遞給塊。 – Thermatix

+0

就是這一點。讓它產生一個枚舉。爲什麼它必須是塊? – Raffael

+0

因爲只是不可能讓它成爲可枚舉的,而不是以代碼結構化的方式進行,並且在塊甚至使用該塊之前該塊會深入幾個方法調用。 – Thermatix

0

嘗試在每次要寫入記錄時打開CSV文件似乎過於複雜並且可能導致性能不佳(除非寫入是間歇性的)。除非將文件模式從wb更改爲ab,否則每次都會覆蓋CSV文件。

我覺得喜歡簡單的東西:

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

會是這樣更容易理解。

相關問題