------art_17237_19830548.1212849297620
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

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:
> > >
> > > > 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> smpleDelegator.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 [] ethods 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); @objj; @var
r; end
    def []; @obj.instance_variable_get(@var); end
    def []al); @obj.instance_variable_set(@var, val); end
end
node  bject.new
node.instance_variable_set(:@next, nil)
node2  bject.new
link  nstanceVariable.new(node, :@next)
p link[] # nil
link[]  ode2
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  value; end
    def []; eval(@lvalue[].to_s, @lvalue.binding); end
    def []al); eval("proc {|v| #{@lvalue[].to_s}  }",
@lvalue.binding)[val]; end
end
def swap(a, b); b[], a[]  [], b[]; end
x  
y  
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

------art_17237_19830548.1212849297620--