From: "Mauricio Fernández" Date: 2003-05-20T17:26:27+09:00 Subject: Re: public/protected/private syntax On Tue, May 20, 2003 at 04:31:05PM +0900, Robert Klemme wrote: > > Then the only differences between anonymous methods and procs would be > > the argument passing semantics and the fact that a method needs to be > > bound, am I right? > > I thought that a proc is bound also: It is indeed, in the sense that 'self' and locals used inside are captured (that's the "closure" part). > Now I'm starting to get confused: What was the difference between a Method > and a Proc? Well, when I said that "a method needs to be bound" I was thinking of UnboundMethod: >> class Foo; def foo; puts "Foo#foo"; end; end => nil >> meth = Foo.instance_method(:foo) => # >> meth.call TypeError: you cannot call unbound method; bind first from (irb):3:in `call' from (irb):3 >> a = Foo.new => # >> meth.bind(a).call Foo#foo => nil With the proposal under consideration, that and the argument passing semantics would be the only differences, I believe. >> def meth(a) >> p a >> end => nil >> pp = proc { |a| p a } => # >> meth(1,2,3) ArgumentError: wrong # of arguments(3 for 1) from (irb):5:in `meth' from (irb):5 >> pp.call(1,2,3) [1, 2, 3] => nil etc > > Will we want to keep both "yield" and "method" > > semantics forever, or will say "yield" be phased out? > > > What about UnboundMethod instances passed as blocks being automatically > > bound to self on #call or yield? > > Interesting thought. However, I'd keep "yield", because it does not need > an explicit reference to the block - and it's kind of at the heart of > Ruby... I was thinking of _not_ needing a reference to the block :) My idea was the following: 1.times def puts "bla" end # => bla def twice yield yield end twice def puts "bla" # => bla end # bla twice def(a) puts a end ArgumentError: wrong # of arguments(0 for 1) So the method passing semantics are defined by the "e-block" (extended block, meaning either proc or UnboundMethod) passed. Then we can have yield and something else for symmetry. More info in [ruby-talk:70189] There's one problem though a = def; p "aa"; end twice a # should this work? def twice(o) yield o yield o end twice "foo" do |x| p x; end twice "foo" def(x) p x; end # should this work??? # ie. is this twice("foo", aMethod) or twice("foo", &block)? solutions: * mandatory '()' with def, significant linebreak twice("foo") def(x) .... end but twice("foo") # LocalJumpError: no block given def(x) end * using & as with Proc twice "foo" &def(x) p x; end I prefer the second one, it makes sense to always use '&' to turn a real "Block" object into an "internalized" block. > > Maybe it's not such a good idea because we'd have to document the > > expected arg. semantics for each method receiving a block... > > But don't we do that already with blocks given to "each", > "each_with_index" etc.? We document the arguments passed, but >> (0..3).each_with_index{ |a| p a } [0, 0] [1, 1] [2, 2] [3, 3] => 0..3 >> (0..3).each_with_index{ |a,| p a } 0 1 2 3 ie. we have assignment semantics. -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com The documentation is in Japanese. Good luck. -- Rich $alz