Bill Kelly
12/4/2004 10:45:00 PM
Hi,
From: "Joe Van Dyk" <joe.vandyk@boeing.com>
>
> What types of methods generally should take blocks?
My most recent use of yield is in a tree-structured database,
where I wanted to be able to perform {some operation} on a
node and all its children. So,
def apply_all(&block)
yield self
@children.each_value {|n| n.apply_all(&block) } if @children
end
The above is a method of the database node class. It
yields itself, and recursively calls apply_all on all of
its children, so they can yield themselves, etc....
So I can use it like:
some_node.apply_all {|n| n.some_method(foo) }
...to call some_method on some_node and all of its children.
My second most recent use of yield was to do some deferred
processing.
@server.rcon_cmd("dmflags #{dmflags}") do |resp|
@server_state['dmflags'] = dmflags.to_s if resp
end
The above wants to send a command to a server, and when the
response is later received, the block is called to perform
some further processing.
The command gets queued and is processed on different
thread. The block, above, is also passed along...
So that, eventually, when the command has been sent to
the server and the server's response has been received,
the block will be called and passed the server's response
as its argument.
I was particularly thrilled with Ruby when writing this,
because originally my code had been written to NOT queue
the commands to the server, but to send the command
immediately and do a blocking wait for the reply... Like,
if resp = @server.rcon_cmd("dmflags #{dmflags}")
@server_state['dmflags'] = dmflags.to_s
end
So I already had a bunch of code like the above, before I
realized that I really wanted to queue the commands and
process their result later. And you can see how little
I needed to change my code to make that happen!
Hope this helps, just a couple ways I've used yield recently.
Regards,
Bill