--s2ZSL+KKDSLx8OML Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 09, 2006 at 03:42:07PM +0900, Victor Shepelev wrote: > Unfortunally, this wouldn't work in statements like: > > adder = proc { |a,b| self.output(a+b) } > add_3 = proc { |a| adder.call(a,3) } # adder bound with b=3 > > class A > def output(val) > puts val > end > end > > A.new.instance_exec(4, &add_3) #want to output 4+3, but receive > #undefined method `output' for main:Object (NoMethodError) > > Also, this bounding is less clear (somebody who would read my code, would > may to think "WTF? Why this strange new proc?" If I'd ever see code like A.new.instance_exec(4, &adder) and I'd have to guess this will, because of currying elsewhere, add 4+3 and call some output function with the result in a rebound environment, my team would hear me screaming in their beds. add_3 is a new proc, because it does something new, with a different set of parameters. Note the original example didn't use class methods, and didn't access self. self in your first line will be bound to the closed over environment (of Object), which is probably not wanted, since this environment has no #output (as of the error message). If you'd want currying of object methods, extend and use (Unbound)Method not Proc. Methods support rebinding to objects without #instance_exec too. Don't blame my code for gross missapplication. If you really want adder to call #output on something you don't know yet when defining the Proc, why not pass that as additional parameter and forego the (not even in 1.8.4) #instance_exec magic that way? And please, name accordingly if you really want clarity: output_sum = proc { |dest,a,b| dest.output(a+b) } output_add3 = proc { |dest,a| output_sum.call(dest,a,3) } output_sum.call(A.new,1,2) # prints 3 output_add3.call(A.new,2) # prints 5 If you need to vary the curried parameter and dont't want to create a mass of procs, remember procs are closures: n = 5 output_add_n = proc { |dest,a| output_sum.call(dest,a,n) } output_add_n.call(A.new,2) # prints 7 n = 6 output_add_n.call(A.new,2) # prints 8 > I think this way: @I do the operation with Proc, > so, the most natural way should be Proc#some_operation". Also, > bind_1st, bind_2nd are C++-like, but I don't understand why we need > such specialized methods in Ruby. At the moment, RubyMurray's > approach seems to me as the most natural: adder = proc { |a,b| > self.output(a+b) } add_3 = adder.curry(Curry::HOLE, 3) Here is no > need to think about argument's numbers. I just provide bounding in > the same order as arguments was. I was thinking functional, as asked for in the original post. Sometimes a functional approach is quite appropriate. Currying object methods (or Procs #instance_exec'd), thereby redefining their interface, isn't clean object oriented design either. Contrary to the traditional functional application, it introduces lots of confusion for small benefit. Classes already have internal state and behaviour depending on message/method name, so no need to reimplement this. It might be useful for some hackish duck typing, but why not just reopen the class, or derive a new one, or add a singleton method, or refactor your proc to a proper, object oriented class? Mabye your first thought was faulty already, why keep using a Proc? class MyCalc def add(a,b) a+b end end class MyCalc attr_writer :n def add_n(a) add(a,@n) end end c = MyCalc.new # instead of a Proc we create a MyCalc c.n = 3 # instead of currying, set an attribute A.new.output(c.add_n(4)) # proper delimination of interfaces: MyCalc # does the adding of n, A does the output. Those last 3 lines can be understood by anyone without knowledge of a library, and seem to do exactly what your example requried. And I bet it is much faster too. It might be slightly more verbose, but that's a feature given the clarity and performance improvement. To answer the original question again: Currying is _sometimes_ useful and powerful for simple functions, and you don't need a library for this. Currying of object methods, or currying of procs to mimic the behaviour of classes, is at most a last resort solution, try something else before it if you value your sanity. Jgen -- The box said it requires Windows 95 or better so I installed Linux --s2ZSL+KKDSLx8OML Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) iQEVAwUBRHQxX/y64gyiEfXtAQIbTQgA8MPnoZ2BZzvCbIRGENeCwYJv+5xmnnKd JU1NT0+GLA/ouGUkpPuUBrjhk8z4pFv9D6K5Ow9kav5VkP7WJxYwdPJIm5wN65Kf AhoeI3MsOC0pHzKyerY1hkzPn7H8lFZqhPCmgIB8NW1iGmkikt8RPs6bVm3W4F/Q fFBlOhaPrw/mKIJbNovj6yme1qBsooeShdN547IlL+wY26+7cpEwBlvCxm6UecI1 R8HDr/uy2H0/6EUSYk+B/+JckuJcgTeeYuP76jGXSGf40cb6RKh0zFjHh2R7HJNJ eQ9dq/lpVJu7LDqYc6MmC7EtY6S2grVrFuZ0zGJ0J5F1fuNspDh16A Bc -----END PGP SIGNATURE----- --s2ZSL+KKDSLx8OML--