"John W. Long" <ng / johnwlong.com> schrieb im Newsbeitrag
news:420AF309.7090306 / johnwlong.com...
> Hi,
>
> I've been messing around a with functors lately (see [1] and [2]) and
have found them really helpful for testing. They make great light-weight
MockObjects. Consider the following example:
>
> Pretend I have a method called redirect that I am trying to test:
>
>     def redirect(url, sys=Kernel)
>       #
>       # code here that writes out an HTTP header
>       # that causes the redirect to url
>       #
>
>       # my header has been written so kill the script:
>       sys.exit
>     end
>
> Given the following definition for a functor I can easily mock out the
sys.exit call:
>
>     class Functor
>       def initialize(method, &block)
>         @method = method
>         @block = block
>       end
>       def method_missing(symbol, *args)
> if @method.to_s.intern == symbol
>    @block.call(*args)
> else
>             super
>          end
>       end
>     end

Just one remark: I'd change that to define the method in the constructor
and not use method_missing as that's more performant.

class Functor
  def initialize(method, &block)
    class << self;self;end.class_eval do
      define_method(method,&block)
    end
  end
end

This variant does not allow for easy adding of methods via Functor#+
though.  But you can easily define a method add(method,&block) that adds a
method and returns self for chaining:

class Functor
  def add(method, &block)
    class << self;self;end.class_eval do
      define_method(method,&block)
    end
    self
  end

  alias :initialize :add
end

Functor.new(:x){puts "x"}.
  add(:y){puts "y"}.
  add(:z){puts "z"}.y


Kind regards

    robert