--------------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> s mpleDelegator.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; name ter.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename ter.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--