From: daz Date: 2003-09-03T22:50:24+09:00 Subject: Re: |rcr|.xv Index Variables ( *_with_index ) From: "why the lucky stiff" > > You know, I think our basic problem concerns metadata. An index is > merely metadata applicable to an iteration cycle. And I don't think > that's the only bit of metadata that could be useful in iteration. The > total number of iterations expected. Even an available reference to the > current block would be great for simpler recursion. > Selectively quoting from your post http://www.ruby-talk.org/56845 ------------------------------------------------------------------------- It would be really cool if, instead of having a million *_with_index methods floating around in Enumerable, we had a method which could be used inside a block to retrieve the number of iterations that the block has undergone. [code snip] The `index' method can then be used in the block: c = z.collect { |el| f(el, a[index], b[index]) } ------------------------------------------------------------------------- def f(r, s, t) [r, s, t] end a = [10, 11, 12] b = [20, 21, 22] z = %w{a b c} c = z.collect { |el|.index f(el, a[index], b[index]) } p c #-> [["a", 10, 20], ["b", 11, 21], ["c", 12, 22]] This, I feel sure you're going to tell me :-), isn't what you wanted. > I think you've done a good job presenting your RCR (although it's really > hard to push syntactical changes with the current parser.) Thanks. To push syntactical changes to Matz or ... ?? I really expected the journey into yacc to be the more difficult of the two parts (173 reduce/reduce conflicts, first attempt; you know the score), but it slotted it quite nicely. > > My concerns: > > 1. If we do want to add more metadata, the syntax becomes cumbersome. If we wanted metadata, we wouldn't do it by passing a Fixnum. > I'm guessing additions would be positional. There is no metadata for a simple index, so no additions. I'm following, all the same :-) > > loop {.index.last print "Item #{ index } of #{ last }." } > loop {.(index,last) print "Item #{ index } of #{ last }." } would cope but that would be getting ugly. If you wanted metadata (which included the block index) you would only need one parameter {.meta } and you'd probably want another valuable piece of data included - the variables passed to the block. I don't think meta[:index] is any improvement on 'with_index'. > If there is no plan for expansion of the syntax, then it become an > _exception_ to Ruby's syntax rather than an _evolution_ of Ruby's > syntax. AFAIK, there is no plan to expand the |parm1, parm2| syntax to be used anywhere other than at the head of a block definition. Both are positional. > > 2. The dot notation looks like a method call. Yet, assignment is > being performed. 3.14159265358979 Method call on Fixnum 3 ?? Familiarity is what dispels that illusion and no-one can be familiar with something that they haven't been introduced to. I used the notation in a position where it couldn't possibly be mistaken for a method call. It follows 'do', '{' or '|'. > It also gives the illusion that the block's > argument list is an object. > And the reason that it's not an object, I suspect, is one of practicality. 2.times do puts meta[:vars[0]] end > > Fun ideas, but you have to think about scoping and the various types of > blocks that commonly float around in Ruby. An index variable has the same scope as a block parameter. As far as I can discern from the code, an xv will pop in and out of scope if it's passed, converted to a proc or whatever you'd normally want to do. Ruby takes care of all that, not me. > > _why > > Thanks for your input and I appreciate that many of your comments were directed towards the wider discussion. It would take a small change to xv.patch to initialise your own Ruby object (class BlockMeta ?) where I've assigned Fixnum 0, which you could refresh where I've incremented. Your object would be available in the block via the xv and you could call your methods on it. 1.times do .x p x.class end #-> Fixnum (could be BlockMeta) daz