From: Gavin Sinclair Date: 2002-10-04T14:10:48+09:00 Subject: Re: Specifying local and external block parameters (that old chestnut) From: "Hal E. Fulton" > From: "Gavin Sinclair" > To: "ruby-talk ML" > Sent: Thursday, October 03, 2002 8:58 PM > Subject: Specifying local and external block parameters (that old chestnut) > > > > I think it makes sense to explicitly mark *external* variables, as > block-local > > variables (parameters, in fact) would be the norm. > > > > Thus, if 'a' and 'c' are regular parameters and 'b' is an external > variable, > > then one could write > > > > collection.each do |a,:b,c| > > ... > > end > > > > or > > > > collection.each do |a,b,c| > > external b > > ... > > end > > > > I'm not sure which of the above I prefer. One should optimise for the > common > > case. > > One problem is that it's not just a simple variable. It > can be anything that responds to assignment. For example, > an accessor: > > 0.upto(99) {|frame.scroll| sleep 0.1} So could 0.upto(99) {|:frame.scroll| sleep 0.1} work? Look quite good, I think, since we are used to :: as a scoping operator. > > I'd like to put a question to the audience :) Does anyone actually have a > need > > to use non-local block parameters? Ever? > > The above is an example. Quite a nice example too, IMO. > Also what if I want the last value(s) of a loop? > > x,i = nil > myobj.each_with_index do |x,i| > # process... > break if some_condition > # more processing... > end > > last_obj = x > last_index = i > > Yes, I *could* save them off in different variables > right before I did the break: > [...] > Two more variables and much ugliness. No, thanks. > > Hal I really dislike relying on finishing values like that, because: - you have to declare variables beforehand - code is harder to understand or be confident that it's right Much better, IMO, is x, i = get_values(myobj) def get_values(obj) obj.each_with_index do |x, i| # process return x, i if some_condition # more processing end end Gavin