On Fri, Feb 21, 2003 at 01:19:17AM +0900, dblack / candle.superlink.net wrote: > Hi -- > > Arising from a recent discussion on #ruby-lang: > > Proc objects created by Method#to_proc seem to care about their arity > in a way that other Proc objects don't. To illustrate: Procs don't care about the arity when they are transformed into blocks with '&': unneeded arguments are discarded and if there's not enough they get filled with nil. >> p = proc { |a,b,c,d,e| p(a) } => #<Proc:0x402ab4b4> >> [1,2,3].each &p (irb):4: warning: `&' interpreted as argument prefix 1 2 3 => [1, 2, 3] >> p.call(1) ArgumentError: wrong # of arguments (1 for 5) from (irb):5 from (irb):3:in `call' from (irb):5 > class A > def talk > puts "hi from A#talk" > end > end > > pr = Proc.new { puts "hi from anonymous Proc" } > methproc = A.new.method(:talk).to_proc > > [1,2,3].each &pr # "hi from anonymous Proc\n" * 3 > [1,2,3].each &methproc # in `talk': wrong # of arguments(1 for 0) > > The #to_proc proc is reacting like a method, not a proc, when given > the "wrong" number of arguments. For me, this doesn't fit in with the > idea of (complete) conversion to a proc. > > Any other thoughts or interpretations of this behavior? Method#to_proc seems to be working like this: batsman@tux-chan:/tmp$ expand -t 2 j.rb class Method def my_to_proc proc { |*args| self.call(*args) } end end class A def talk puts "A#talk" end end methproc = A.new.method(:talk).my_to_proc [1,2,3].each(&methproc) batsman@tux-chan:/tmp$ ruby j.rb j.rb:4:in `talk': wrong # of arguments(1 for 0) (ArgumentError) from j.rb:4:in `call' from j.rb:4:in `my_to_proc' from j.rb:4:in `each' from j.rb:15 You can make it behave like a "real" proc with the following: batsman@tux-chan:/tmp$ expand -t 2 k.rb class Method def my_to_proc case when arity > 0 proc do |*args| (arity - args.size).times() { args << nil } if arity > args.size self.call(*(args[0,arity])) end when arity == 0 proc { |*args| self.call } when arity < 0 rarity = -1 - arity proc do |*args| (rarity - args.size).times() { args << nil } if rarity > args.size self.call(*args) end end end end class A def talk puts "A#talk" end def var_arg(a,b,c,*others) p a,b,c, others end def normal(a,b,c) p a,b,c end end methproc = A.new.method(:talk).my_to_proc m2 = A.new.method(:var_arg).my_to_proc m3 = A.new.method(:normal).my_to_proc [1].each(&methproc) [1].each(&m2) [1].each(&m3) batsman@tux-chan:/tmp$ ruby k.rb A#talk 1 nil nil [] 1 nil nil -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com Save yourself from the 'Gates' of hell, use Linux." -- like that one. -- The_Kind @ LinuxNet