From: Ben Giddings Date: 2004-09-09T11:33:16+09:00 Subject: Re: ruby-dev summary 24171-24235 On Sep 8, 2004, at 05:29, Minero Aoki wrote: > idx = "foo bar".index(/oo/) # compatible with current code > idx, m = "foo bar".index(/oo/) # m = $~ > > "foo bar".gsub(/oo/) do |str| # compatible with current code > .... > end > "foo bar".gsub(/oo/) do |str, m| # m = $~ > .... > end > > On the other hand, this scheme breaks codes which use > `auto composite' feature of multiple assignment: > > h = {1=>3, 2=>9, 3=>27} > h.each do |pair| > p pair #=> [1,3] now, but 1 by this proposal > end To me, this isn't a big loss. It improves readability / understandability. h = {1=>3, 2=>9, 3=>27} h.each do |a,b| p a end h.each do |a| p a end At a glance, I'd expect both of those methods to do the same thing. I think that's the more natural behaviour. An additional benefit is that with this mechanism, 'yield' can pass much more information, in expected order of usefulness, and you can add parameters if you wish. For example if internally Array#each used a "yield element,index,num_left" you could do: arr = ["cat", "dog", "bat", "log"] arr.each do |e| print "#{e}, " end => cat, dog, bat, log, arr.each do |e, i, remain| print e print "," unless 0 == remain end => cat, dog, bat, log If I wanted every parameter that 'yield' passes, I'd expect to have to do h.each do |*a| p a end I like Kristof Bastiaensen's idea of pattern matching > [[1, 3], [2, 9], [3, 27]].each do |[arg1, arg2]| > p arg1.inspect #=> 1 > p arg2.inspect #=> 2 > end But I'm not sure how radical a change that would be to the language, or how easy it would be to do. I also wonder if there's some way of integrating the named parameters into this. arr = ["cat", "dog", "bat", "log"] arr.each do |index: i, element: e| print "#{e}, " end I really like named parameters, because they further insulate you from changes, and allow people writing libraries to keep adding features without worrying about breaking backwards compatibility. Just a thought, Ben