thesecretmaster
thesecretmaster

Reputation: 1984

How to run stored block?

I have a class that stores blocks, and I would like to run a block later. How can I run it?

class StoreBlocks
  @@blockarray = []
  def initialize
    @storedblock = yield
    @@blockarray << self
  end
  attr_reader :storedblock
  def self.getblock
    @@blockarray
  end
end

StoreBlocks.new do
  # cool codey stuff
end

# do other things

How would I run StoreBlocks.getblock[0].storedblock?

Upvotes: 1

Views: 94

Answers (2)

Borsunho
Borsunho

Reputation: 1157

= yield would assign the return value of passed block, not the block itself. You would need to change your class to something like this:

class StoreBlocks
  attr_accessor :storedblock
  @@blockarray
  def initialize &block
    @storedblock = block
    @@blockarray << self
  end
  def self.getblock
    @@blockarray
  end
end

& means that block passed to initialize will be converted to Proc and assigned to argument named block, and than you can store it in instance variable. You could than call it like:

StoreBlocks.getblock[0].storedblock.call()

Upvotes: 1

Chris Wilding
Chris Wilding

Reputation: 557

yield will imediately call the block passed to initalize. This means that @storeblock will contain the result of calling yield not the block itself. FYI, you are not putting @storedblock into @@blockarray

If you want to store a block you can do something like this -

class BlockStore
  def initialize
    @blocks ||= []
  end

  def add_block(&block)
    @blocks << block
  end

  def run_all_blocks
    @blocks.each do |block|
      block.call
    end
  end
end

block_store = BlockStore.new
block_store.add_block do
  puts 'Hello!'
end
block_store.add_block do
  puts 'World!'
end
puts 'About to run all blocks'
block_store.run_all_blocks

This gives you an output like the below. I've output 'About to run all blocks' before running the blocks to show that they are stored and then run later -

➜  ruby blocks.rb 
About to run all blocks
Hello!
World!

Upvotes: 1

Related Questions