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.

>> External iterators are also like lvalue references and is something
>> ruby is missing (IMHO).
>
> Is it?
>
> irb(main):027:0> require 'generator'
> => true
> irb(main):028:0> arr = %w{foo bar baz}
> => ["foo", "bar", "baz"]
> irb(main):029:0> it = Generator.new arr
> => #<Generator:0x1002ffe8 @cont_endp=nil, @index=0,
> @block=#<Proc:0x1001bbc4@/usr/lib/ruby/1.8/generator.rb:71>,
> @cont_yield=#<Continuation:0x1002f5fc>, @cont_next=nil, @queue=["foo"]>
> irb(main):030:0> until it.end?; puts it.current; it.next; end
> foo
> bar
> baz
> => nil

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.

>> 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.

> 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.

Eric