From: Ross Bamford Date: 2006-01-03T05:32:57+09:00 Subject: Implicit block parameter? Hi, Probably this has been considered before, but I'll ask anyway. Before I used Ruby, I used Groovy. In some ways they are (well, were anyway) quite similar, and one feature that I found cool in Groovy that I often miss in Ruby is the implicit (/default/whatever?) block parameter, 'it': [1,2,3].each { puts it } AFAIR this was only provided when no 'it' existed in scope, and the block had a single argument passed when none were declared. Maybe this would interfere with Ruby's warnings about block parameter mismatch, or maybe the implementation doesn't allow for it, but I just wondered if it might be possible, because I notice I do: [1,2,3].each { |it| puts it } and it bugs me a little bit :D I did try hacking it from the Ruby side and came up with a halfway solution using instance variables and the Binding extension from Rubyforge: require 'rubygems' require 'extensions/binding' def itproc(&blk) class << blk def [](*args) if args.length == 1 begin old = binding[:@it] binding[:@it] = args[0] super ensure binding[:@it] = old end else super end end alias :call :[] end blk end But of course this doesn't work with regular procs (doing it on Proc causes a segfault here, I guess because extensions uses procs itself to do the binding stuff?) and of course it doesn't happen with yielded blocks, even when passed from procs: pr = itproc { puts "@it = #{@it.inspect}" } pr2 = itproc { |one| puts "@it = #{@it.inspect}; one = #{one.inspect}" } pr3 = itproc { |a, b| puts "@it = #{@it.inspect}; a = #{a.inspect}; b = #{b}" } # Works puts "Call" pr.call('Hello') pr2.call('Hello') pr3.call('He','llo') # Works puts "\n[]" pr['Bye'] pr2['Bye'] pr3['Bye','Bye'] # Doesn't work through yield though :( puts "\nYield" [1,2,3].each &pr [1,2,3].each &pr2 [1,2,3].each &pr3 Anyway, it's a bit of an abuse of instance vars I guess, and obviously doesn't do the job properly - I wonder if anyone else has thought about this, and whether it's something that doesn't already exist in Ruby itself for a reason? Cheers, -- Ross Bamford - rosco@roscopeco.remove.co.uk