>
> >
> > > another solution: a) pass the node containing the link you want to
> > > operate along with something saying which link in the node (you'll
> > > probably also need a dummy node at the root/head), b) have a
separate
> > > object for the link so you can pass it around (i.e. simply an Array
of
> > > one element), c) pass a lambda that can modify the link. None of
> > > these are as elegant as an lvalue reference IMHO. In my early ruby
> > > days a few years ago I put some code in the rubyforge "reference"
> > > project. I still think having something like this readily available
> > > would be useful.
> > >
> > The usual solution in Ruby would probably be a) which I find perfectly
ok.
> > Since the manipulation is typically encapsulated inside a LinkedList
class
> > it does not bother me too much if there are two additional elements
(for
> > head and tail).
But I can see how this might be a bit more
elegant
with
> > references (although not as much to create an urgent need for
references
in
> > Ruby). 
> >
>
> Definitely no urgent need, but a nice thing to have in a bag of
> tricks. It could be implemented in Ruby, but you'll get more
> efficiency if done in C (ruby implementation would typically need eval
> - at least for local vars). No special syntax needed.
>
Acutally, there *is* an implementation already:
irb(main):002:0> s=SimpleDelegator.new nil
=> nil
irb(main):003:0> s.__getobj__
=> nil
irb(main):004:0> s.__setobj__ "foo"
=> "foo"
irb(main):005:0> s
=> "foo"
irb(main):006:0> s.__getobj__
=> "foo"
irb(main):007:0> s.__setobj__ "bar"
=> "bar"
irb(main):008:0> s.__getobj__
=> "bar"
irb(main):009:0> s.length
=> 3
irb(main):010:0> s.gsub /./, 'X'
=> "XXX"

But, this doesn't give you an lvalue reference, just an anonymous reference
(which could be used for a case b implementation). A one element Array
would work just as well:
s = ["foo"]
p s[0] # => "foo"
s[0] = "bar"
p s[0] # => "bar"
I usually make a little class with and = methods that take no args in
the , so I don't need the "0" and the suffix is equivalent to the *
prefix in C/C++.
Here would be an fairly efficient instance variable lvalue reference class:
class InstanceVariable
def initialize(obj, var); @obj=obj; @var=var; end
def ; @obj.instance_variable_get(@var); end
def =(val); @obj.instance_variable_set(@var, val); end
end
node = Object.new
node.instance_variable_set(:@next, nil)
node2 = Object.new
link = InstanceVariable.new(node, :@next)
p link # => nil
link = node2
p link.equal?(node2) # => true
p node.instance_variable_get(:@next).equal?(node2) # => true
Here would be a more general class for referencing any lvalue:
class LValue
def initialize(&lvalue); @lvalue = lvalue; end
def ; eval(@lvalue.to_s, @lvalue.binding); end
def =(val); eval("proc {|v| #{@lvalue.to_s} = v}",
@lvalue.binding)[val]; end
end
def swap(a, b); b, a = a, b; end
x = 1
y = 2
swap(LValue.new { :x }, LValue.new { :y })
p x # => 2
p y # => 1
> #zip doesn't help if you want to write, back-up, insert, delete, etc
> during iteration.
>
Correct. For Array this could easily be build as an external class
(attached is an experimental version).
For Array, there isn't a whole lot of value for an external iterator,
because we already have something that works as a poor man's replacement -
index (an integer). The index can't do its own dereferencing (to read and
write an element), but Array can using an index. In C++ STL, an external
iterator can't do all operations either. To do an erase or insert for
example, you call a method on the container with an iterator.
I think external iterators are more useful for other data structures where
you don't have random access - linked lists, trees, etc. I guess you could
provide an index-like API (but the index might not be an integer) instead of
a normal external iterator.
BTW, another external iterator we already have is IO, which operates at a
specific point in a file.
Eric
···
On 6/7/08, Robert Klemme <shortcutter@googlemail.com> wrote:
On 07.06.2008 04:30, Eric Mahurin wrote:
> On Fri, Jun 6, 2008 at 10:49 AM, Robert Klemme > > <shortcutter@googlemail.com> wrote:
> > On 06.06.2008 17:01, Eric Mahurin wrote: