--------------040505040604000407060103
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

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"

:-)

>>> External iterators are also like lvalue references and is something
>>> ruby is missing (IMHO).
>> Is it?
>>
>> irb(main):027:0> require 'generator'

> This just gives a very limited external iterator that can read and
> move forward (just like an internal iterator).  In C++ terms, this
> corresponds to one of the simplest - "Input Iterator".  Other
> operations you might want to do where the iterator is at would be:
> write, move back, insert, delete, random access.

Right you are.

>>> An external iterator could be thought of as a
>>> superset of the reference/pointer concept (external iterator looks
>>> like a pointer in C++).
>> Which is nicely done (in C++'s STL, I mean).  But with blocks I don't really
>> miss external iterators.  I rarely have to iterate through multiple
>> collections in lock step and if I had #zip served me well.
> 
> #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).

>> Maybe I'm just not doing enough development that involves sophisticated
>> algorithms. :-)
> 
> Well, the last year or so I've been exposed to quite a bit of
> computational geometry and graph theory.  Most of that has been in C++
> and a bit of Python (would have used Ruby, but needed a certain API).
> Outside of that, my experience would say the same as you.  Usually
> simple data structures and access methods suffice.

Thank you for this exchange!

Kind regards

	robert


--------------040505040604000407060103
Content-Type: text/plain;
 nameter.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filenameter.rb"

#!/bin/env ruby

class Array
  class ArrayIterator
    def initialize(ar,pos)
      @array  r
      @pos    os
      @fw     os >  # hack to get #remove working
    end

    def value
      ensure_valid
      @array[@pos]
    end

    def value al
      ensure_valid
      @array[@pos]  al
    end

    def insert val
      ensure_valid
      @array[@pos,0]  al
    end

    def remove
      ensure_valid
      x  array.delete_at @pos
      @pos -  if @fw
      x
    end

    def next?
      @fw  rue
      @pos < @array.size - 1
    end

    def next
      raise "At end" unless next?
      @fw  rue
      @array[@pos + ]
    end

    def previous?
      @fw  alse
      @pos > 0
    end

    def previous
      raise "At beginning" unless previous?
      @fw  alse
      @array[@pos - ]
    end

    def valid?
      @pos >  && @pos < @array.size
    end

  private
    def ensure_valid
      raise "Invalid" unless valid?
    end
  end

  def iterator(pos  )
    raise IndexError unless pos > 1 - length && pos < length
    ArrayIterator.new self, pos < 0 ? length + 1 + pos : pos - 1
  end
end

a  1..5).to_a
p a
it  .iterator

while it.next?
  it.next
  puts it.value + 0
end
p a

it  .iterator -1

while it.previous?
  it.previous
  puts it.value - 
end
p a

it  .iterator

while it.next?
  it.next

  if it.value % 2 0
    it.remove
  else
    puts it.value + 3
  end
end
p a

--------------040505040604000407060103--