rubyruby-block

I have a conundrum involving blocks and passing them around, need help solving it


Ok, so I've build a DSL and part of it requires the user of the DSL to define what I called a 'writer block'

  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

The writer block gets called like this:

  def pull_and_store
    raise "No writer detected" unless @writer
    @writer.call( -> (&block) {
      pull(pull_initial,&block)
    })
  end

The problem is two fold, first, is this the best way to handle this kind of thing and second I'm getting a strange error:

undefined method data_block' for Servo_City:Class (NoMethodError)

It's strange becuase I can see data_block right there, or at least it exists before the CSV block at any rate.

What I'm trying to create is a way for the user to write a wrapper block that both wraps around a block and yields a block to the block that is being wrapped, wow that's a mouthful.


Solution

  • Inner me does not want to write an answer before the question is clarified.
    Other me wagers that code examples will help to clarify the problem.


    I assume that the writer block has the task of persisting some data. Could you pass the data into the block in an enumerable form? That would allow the DSL user to write something like this:

    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
    

    No block passing required.

    Note that you can pass in a lazy collection if dealing with hugely huge data sets.

    Does this solve your problem?