From: Sam McCall Date: 2004-08-12T20:26:16+09:00 Subject: [proto-rcr] Blocks: default arguments and method signatures I thought I'd post these ideas here, since last time I wrote up an RCR and then got told that the issue had already been addressed in plans for Ruby 2. Also, some ideas I'm pretty happy with, some are quite radical/provocative. Hopefully those latter bits are somewhat independent, which ones do you like? (if any ;) So please let me know if I'm missing something, or this could be done better. 1) Default arguments for &block Often a method performs some simple reasonably useful behaviour if no block is given, otherwise it lets the block do something more useful. For example: def transform_values(array) out=[] unless block_given? array.each { |value| # calculations... if block_given? yield value,newvalue else out<< newvalue end } out end I propose &block could take a default argument, probably of the form &block={|x| foo}, but I could live with &block=proc {|x| foo}. block_given? would return *false* if the default value was used (I'm flexible on this bit). The default block would be scoped *inside* the method. That example would become: def transform_values(array) &block={|val,newval| out<< newval} out=[] unless block_given? array.each { |value| #calculations... yield value,newvalue } end 2) Taking anonymous block parameter, making it part of the signature Two issues: a) If block default values are adopted, then giving the block a name might sometimes seem silly, as the name's never used. See the above example, "block" is never referenced. b) No way to specify taking a block as part of method signature. Descrptive signatures are good: * See syntax in auto-docs/code without reading whole thing * See syntax in auto-docs/code when there's no comments * Flag errors at start of method, and on every invocation. Proposal: allow "&" in place of "&block": def foo & (or maybe: def foo &!) As soon as the method is called, raises an error if no block is given (similar to wrong number of args) def foo &? (or maybe: def foo &) No change from current behaviour of def foo, but denotes that this method can take a block and might use it if given. (MAYBE:) def foo &block! or def foo &!block or replace current meaning(!) of: def foo &block This method is required to take a block, not passing a block raises an error. def foo &block or def foo &block? or def foo &?block, etc Current meaning of &block. My preferred syntax in a throw-everything-away-for-Ruby2 scenario: Named block Anonymous block Disallowed def foo def foo Optional def foo &block? def foo &? Defaulted def foo &block={} def foo &={} Compulsory def foo &block def foo & My preferred syntax in a backwards-compatible scenario: Named block Anonymous block Disallowed - - Optional def foo &block def foo &? Defaulted def foo &block={} def foo &={} Compulsory def foo &block! def foo &! Thoughts? Sam