[#1551] Hashes as keys — "Nathaniel Talbott" <nathaniel@...>

I was just playing around with Hash#hash and discovered that you can't use a

13 messages 2003/09/23

Re: |rcr|.xv Index Variables ( *_with_index )

From: "daz" <dooby@...10.karoo.co.uk>
Date: 2003-09-03 13:39:52 UTC
List: ruby-core #1504
From: <george.marrows@ps.ge.com>


> 
> What about hashes? Could/should the keys get passed to the index variable?

No, because you can use any current iterator which passes
the key as a block parameter and use the xv if you have a
need for it.  That's all.

 hsh = {'a'=>1, 'b'=>2}

 hsh.each_with_index {|e,    ix| p [ e[0], e[1], ix ]}
 hsh.each            {|k, v|.ix  p [ k   , v   , ix ]}

These lines have eqivalent output but there are no
equivalents for #fetch, #reject, #each_key etc. in
a similar situation.

> That way the scan exceptions start to look like a general rule: the index
> variable is whatever makes most sense for the given method. 

It does seem to make sense when scan is iterating internally on
the bytes in a string but only yielding to its block when it
finds some useful information (a match).  Externally (in the block),
it could be argued that (iter+1) is bogus information.

> 
> Isn't it effectively just another arg yielded by an iterator, the difference
> being that the block only needs to bother with it if it's interested.

Sort of but (as Gavin said) it's 'automatic'.  Adding another argument
would need a change to the yield in the method and to any block
which may get attached to the method.

> 
> Dave - how would write a method in Ruby which supplied an index variable?

As an afterthought, I used the Ruby API's  rb_define_virtual_variable()
described in PickAxe:

  Exports a virtual variable to Ruby namespace as the global $name.
  No actual storage exists for the variable; attempts to get and set
  the value will call the given functions.

So, $XITER  will get, $XITER=  will set the index variable associated
with the block which is in scope where the virtual var is used.

def roo
  # ...
  $XITER = 6
  # ...
  yield 'xx', 'yy'
  # ...
end

roo do |a, b|.xv
  p [xv, a, b]
end

#-> [6, "xx", "yy"]

I'd encourage you to apply the patch and try things out.
I'm quite confident that it won't upset your normal work
because of its narrow focus.
Any block which doesn't have an xv has a zero pointer
which prevents an interference from the tiny changes
to the interpreter.

> 
> -- George 
> 


daz




In This Thread

Prev Next