Reputation: 1984
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
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
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