From: elbows@... (Nathan Weston) Date: 2003-10-04T01:11:37+09:00 Subject: Re: robust-iterator; detaching observers automaticly ? You could use a block, a la File.open {}: robust_array.create_iterator { |i| do some stuff with the iterator... } Where the iterator is created and passed to the block, and then detached after the block is executed. or even robust_array.each { |x| ... } where the each is implemented with a robust iterator. Neither of these solves the clone problem, but it at least makes things easy in the common case. Nathan Simon Strandgaard wrote in message news:... > I am working on a Robust-Iterator (tm).. where the iterators > gets registerd at the data-structure they traverse. > When doing insert/remove in the data-structure, then the iterators > still points to the same element. > Clone such an iterator will add an extra observer to the list. > > What I cannot figure out is how to detach observers when an iterator is no > longer used.. kind of similar to the Ruby-destructor problem. > > Question#1: should I introduce a #close method in all my object ? > > Question#2: how do you unregister objects (pseudo automaticly) ? > > -- > Simon Strandgaard > > > > server> cat robust.rb > require 'iterator' > require 'observer' > > # purpose: > # a array with robust iterators > # > # functions: > # * iterators keeps pointing to the same element, > # when doing insert/remove (primary feature). > # * normal array behavier. > # > # issues: > # * you must #detach allocated iterators. > class RobustArray > # purpose: > # a robust iterator, which keeps its position > # even though you insert/remove elements. > # > # functions: > # * in case of changes in the array the iterator > # gets notify from the parent about the change. > # * #clone attaches the new instance to the parent. > # > # todo: > # * policies for how the iterator should behave > # detach_on_remove, prev_on_remove, next_on_remove > class Iterator < Iterator::Collection > def initialize(data) > super(data) > @data.add_observer(self) > end > def clone > instance = super > @data.add_observer(instance) > instance > end > def detach > @data.delete_observer(self) > @data = nil > @position = nil > end > def update(where, delta) > if delta > 0 > if @position >= where > @position += delta > end > elsif (where+delta..where).member?(@position) > detach # remove ourselves from the iterator list > elsif @position >= where > @position += delta - 1 > end > end > end > > include Observable > def initialize(ary) > @data = ary > end > def to_a > @data > end > def size > @data.size > end > def [](index) > @data[index] > end > def []=(index, value) > @data[index] = value > end > def RobustArray.build_from_array(ary) > RobustArray.new(ary) > end > def create_iterator > Iterator.new(self) > end > def remove(range) > res = @data.slice!(range) > a = range.first > b = range.last > changed > notify_observers(b, -(b-a)) > RobustArray.build_from_array(res) > end > def insert(where, data) > ary = data.to_a > @data[where, 0] = ary > changed > notify_observers(where, ary.size) > end > end > server>