"Curt Sampson" <cjs / cynic.net> schrieb im Newsbeitrag
news:Pine.NEB.4.62.0504131544280.19224 / angelic.cynic.net...
> On Wed, 13 Apr 2005, Gennady Bystritsky wrote:
>
> > Oh, yes, a block is used to define a class body, I see. However, "def"
> > syntax prevents "foo" from being treated as a closure participant. At
> > least, it is how it looks to me ;-).
>
> Bingo! After a bit more playing, it looks like the "class" statement
> does this too.
>
> This is not so hard to live with, once you know. The problem is, the
> language makes finding out this stuff so darn tough.
>
> If you want to see what this was all about, I've appended a nifty little
> bit of code. (I'm using it with a factory that stores Classes, and
> later instantiates them; this saves me having to store parameters for
> new as well.) It took me quite some time to work out that I had to use
> define_method instead of def.
>
> cjs
> -- 
> Curt Sampson  <cjs / cynic.net>   +81 90 7737 2974   http://www.NetBSD.org
>       Make up enjoying your city life...produced by BIC CAMERA
>
>
> # $Id: curry.rb,v 1.1 2005/04/13 05:41:38 cjs Exp $
>
> require 'test/unit/testcase'
>
> def curryclass(klass, *curried_args)
>      curried_class = Class.new(klass) {
>   def initialize(*args)
>       super_args = curried_args + args
>       super(*super_args)
>   end
>      }
>      curried_class
> end

I'd probably do it either of these ways:

# straightforward, but need to invoke #call
def curryclass(cl,*args)
  lambda { cl.new(*args) }
end

# if you need "new"
def curryclass(cl,*args)
  l = lambda { cl.new(*args) }
  class <<l; alias :new :call; end
  l
end

# another way
def curryclass(cl,*args)
  o = Object.new
  class <<o;self;end.define_method(:new){cl.new(*args)}
  o
end

Kind regards

    robert


> class TC_curryclass < Test::Unit::TestCase
>
>      class AddPair
>   def initialize(a, b)
>       @value = a + b
>   end
>   attr_reader :value
>      end
>
>      AddTwoAndFour = curryclass(AddPair, 2, 4)
>
>      AddTwo = curryclass(AddPair, 2)
>
>      def FAILING test_curryclass
>   assert_equal(5, self.class::AddPair.new(2, 3).value)
>   assert_equal(6, self.class::AddTwoAndFour.new.value)
>   assert_equal(7, self.class::AddTwo.new(5).value)
>      end
>
>      def test_nothing
>      end
>
> end
>
>