I've got some code that looks like the following. First, there's a simple Parser class for parsing command-line arguments with options.
class Parser
  def initialize(&b); ...; end      # Create new parser.
  def parse(args = ARGV); ...; end  # Consume command-line args.
  def opt(...); ...; end            # Declare supported option.
  def die(...); ...; end            # Validation handler.
end
Then I have my own Parsers module which holds some metadata about parsers that I want to track.
module Parsers
  ParserMap = {}
  def self.make_parser(kind, desc, &b)
    b ||= lambda {}
    module_eval {
      ParserMap[kind] = {:desc => "", :validation => lambda {} }
      ParserMap[kind][:desc] = desc
      # Create new parser identified by `<Kind>Parser`. Making a Parser is very
      #   expensive, so we defer its creation until it's actually needed later
      #   by wrapping it in a lambda and calling it when we actually need it.
      const_set(name_for_parser(kind), lambda { Parser.new(&b) })
    }
  end
  # ...
end
Now when you want to add a new parser, you can call make_parser like so:
make_parser :db, "login to database" do
  # Options that this parser knows how to parse.
  opt :verbose, "be verbose with output messages"
  opt :uid, "user id"
  opt :pwd, "password"
end
Cool. But there's a problem. We want to optionally associate validation with each parser, so that we can write something like:
validation = lambda { |parser, opts|
  parser.die unless opts[:uid] && opts[:pwd]  # Must provide login.
}
The interface contract with Parser says that we can't do any validation until after Parser#parse has been called. So, we want to do the following:
Associate an optional block with every Parser we make with make_parser.
We also want to be able to run this block, ideally as a new method called Parser#validate. But any on-demand method is equally suitable.
How do we do that?