From: Eric Hodel Date: 2007-11-16T18:19:45+09:00 Subject: Re: "&prock", not "&block" On Nov 15, 2007, at 13:06 , Greg Weeks wrote: > Eric Hodel wrote: >> Class doesn't matter, methods do. > > You're preaching to the choir :-) > >> I'm (almost) always passing in a block, so its a block. > > If you're passing in a block, then the method parameter is something > like "&foo". You can't make a variable &foo. def x(&foo); end Says that if you pass in a block, assign it to the foo variable. mything = ... x(&mything) Says call mything.to_proc and pass that result as a block to #x. If you see & used outside of those two contexts, it is the & method. > If you're passing in a proc, then the message parameter is > something like "foo". In either case, in the method body, "&foo" > is a block, and "foo" is a proc. Class and type don't matter, methods do. If I call x(&5), Ruby will call 5.to_proc for me and pass the result of that along. If I try to use &foo as a variable, ruby gives a syntax error. You can only use &foo for describing a method argument, or for passing an argument to a method. > It may be that "&foo" is pedagogically described as the "foo" > parameter > with an "&" modifier. But that is misleading. This is correct, and this is what happens. Its not misleading. &foo works the same as *foo. If I put *foo in the method signature, all the arguments will be collected into foo as an Array, like &foo collects a block into foo as a Proc. If I call a method and use *foo as one of the parameters, Ruby will call foo.to_ary and pass the results to the method like &foo calls foo.to_proc. Both *foo and &foo are optional. You won't get an ArgumentError if you omit an item with *foo or a block with &foo. If * is the "splat" operator, & is the "block splat" ("blockify"?) operator. > The block argument is bound to "&foo", not to "foo". And the block > argument is accessible in the method body -- as "&foo". No, it is bound too foo, not &foo. &foo is not a variable name. > So in all cases, "&foo" is a block iff "foo" is a proc. def z(&foo) p foo end z() # => nil -- Poor workers blame their tools. Good workers build better tools. The best workers get their tools to do the work for them. -- Syndicate Wars