On 5/28/07, Robert Klemme <shortcutter / googlemail.com> wrote:
> > Well the idea is to wrap an object with this proxy class and not mess
> > up any code that doesn't know about it... it should seem completely
> > transparent. It gives you a separate namespace for methods and
> > instance variables, so you don't have to worry about redefining those
> > with a mixin or singleton method, but you can still specialize some
> > object by wrapping it.
>
> Yes, you said so earlier.  But what business problem are you trying to
> solve?

I'm not trying to solve a business problem (I'm not sure what you
mean?).  I would think this is something more like a design pattern,
like http://home.earthlink.net/~huston2/dp/proxy.html

Here's some code that implements it

class Object
  def self.=== other
    #puts "object #{self} === #{other}"
    other.is_a? self
  end
end

class Thunk
  instance_methods.each do |m|
    undef_method m unless m =~ /^__/
  end

  def initialize &block
    @proc = block
    @computed = false
  end

  def method_missing method, *args, &block
    unless @computed
      puts "computing value"
      @computed = true
      @value = @proc.call
    end
    @value.send method, *args, &block
  end
end

$stdout.sync = true

# the block isn't called until any message is sent to x, this way
# if x is never used (maybe there's a condition that prevents this)
# we'll never have to bother performing a slow computation
x = Thunk.new { sleep 5; 'expensive computation...'; 50000 }; nil

if Time.now.sec.modulo(2).zero? # even
  puts "value: #{x}"
end

Regards,
  Erwin

PS: Yes, I am aware there have been other ruby projects that do
similar things. This is just an example, where any code that's passed
a "Thunk" doesn't need to know it's anything special... unless it's
using a case statement to check if it implements a mixin ;-)