[#83328] tcltklib and not init'ing tk — aakhter@... (Aamer Akhter)

Hello,

13 messages 2003/10/01

[#83391] mixing in class methods — "Mark J. Reed" <markjreed@...>

Okay, probably a dumb question, but: is there any way to define

22 messages 2003/10/01
[#83392] Re: mixing in class methods — Ryan Pavlik <rpav@...> 2003/10/01

On Thu, 2 Oct 2003 06:02:32 +0900

[#83397] Re: mixing in class methods — Gavin Sinclair <gsinclair@...> 2003/10/01

On Thursday, October 2, 2003, 7:08:00 AM, Ryan wrote:

[#83399] Re: mixing in class methods — "Mark J. Reed" <markjreed@...> 2003/10/02

On Thu, Oct 02, 2003 at 07:37:25AM +0900, Gavin Sinclair wrote:

[#83404] Re: mixing in class methods — "Gavin Sinclair" <gsinclair@...> 2003/10/02

> On Thu, Oct 02, 2003 at 07:37:25AM +0900, Gavin Sinclair wrote:

[#83416] C or C++? — "Joe Cheng" <code@...>

I'd like to start writing Ruby extensions. Does it make a difference

32 messages 2003/10/02
[#83435] Re: C or C++? — "Aleksei Guzev" <aleksei.guzev@...> 2003/10/02

[#83448] xml in Ruby — paul vudmaska <paul_vudmaska@...> 2003/10/02

The biggest problem i have with Ruby is the sleepness

[#83455] Re: xml in Ruby — Chad Fowler <chad@...> 2003/10/02

On Thu, 2 Oct 2003, paul vudmaska wrote:

[#83464] Re: xml in Ruby or no xml it's just a question — paul vudmaska <paul_vudmaska@...> 2003/10/02

>>--------

[#83470] Re: xml in Ruby — paul vudmaska <paul_vudmaska@...>

>>>

15 messages 2003/10/02

[#83551] xml + ruby — paul vudmaska <paul_vudmaska@...>

>>---------

20 messages 2003/10/03
[#83562] Re: xml + ruby — Austin Ziegler <austin@...> 2003/10/03

On Fri, 3 Oct 2003 16:11:46 +0900, paul vudmaska wrote:

[#83554] hash of hashes — Paul Argentoff <argentoff@...>

Hi all.

18 messages 2003/10/03

[#83675] fox-tool - interactive gui builder for fxruby — henon <user@...>

hi fellows,

15 messages 2003/10/05

[#83730] Re: Enumerable#inject is surprising me... — "Weirich, James" <James.Weirich@...>

> Does it surprise you?

17 messages 2003/10/06
[#83732] Re: Enumerable#inject is surprising me... — nobu.nokada@... 2003/10/07

Hi,

[#83801] Extension Language for a Text Editor — Nikolai Weibull <ruby-talk@...>

OK. So I'm going to write a text editor for my masters' thesis. The

35 messages 2003/10/08
[#83803] Re: Extension Language for a Text Editor — Ryan Pavlik <rpav@...> 2003/10/08

On Thu, 9 Oct 2003 05:06:32 +0900

[#83806] Re: Extension Language for a Text Editor — Nikolai Weibull <ruby-talk@...> 2003/10/08

* Ryan Pavlik <rpav@mephle.com> [Oct, 08 2003 22:30]:

[#83812] Re: Extension Language for a Text Editor — Ryan Pavlik <rpav@...> 2003/10/08

On Thu, 9 Oct 2003 06:09:29 +0900

[#83955] Re: Extension Language for a Text Editor — Nikolai Weibull <ruby-talk@...> 2003/10/09

* Ryan Pavlik <rpav@mephle.com> [Oct, 09 2003 09:10]:

[#84169] General Ruby Programming questions — Simon Kitching <simon@...>

21 messages 2003/10/15
[#84170] Re: General Ruby Programming questions — Florian Gross <flgr@...> 2003/10/15

Simon Kitching wrote:

[#84172] Re: General Ruby Programming questions — Simon Kitching <simon@...> 2003/10/15

Hi Florian..

[#84331] Re: Email Harvesting — Greg Vaughn <gvaughn@...>

Ryan Dlugosz said:

17 messages 2003/10/21
[#84335] Re: Email Harvesting — Hugh Sasse Staff Elec Eng <hgs@...> 2003/10/21

On Wed, 22 Oct 2003, Greg Vaughn wrote:

[#84343] Re: Email Harvesting — Ruben Vandeginste <Ruben.Vandeginste@...> 2003/10/22

On Wed, 22 Oct 2003 08:35:32 +0900, Hugh Sasse Staff Elec Eng

[#84341] Ruby-oriented Linux distro? — Hal Fulton <hal9000@...>

There's been some talk of something like this in the past.

15 messages 2003/10/22
[#84348] Re: Ruby-oriented Linux distro? — Gavin Sinclair <gsinclair@...> 2003/10/22

On Wednesday, October 22, 2003, 6:01:16 PM, Hal wrote:

[#84351] Re: Ruby-oriented Linux distro? — Andrew Walrond <andrew@...> 2003/10/22

On Wednesday 22 Oct 2003 11:02 am, Gavin Sinclair wrote:

[#84420] Struggling with variable arguments to block — "Gavin Sinclair" <gsinclair@...>

Hi -talk,

18 messages 2003/10/24
[#84428] Re: Struggling with variable arguments to block — matz@... (Yukihiro Matsumoto) 2003/10/24

Hi,

[#84604] ruby-dev summary 21637-21729 — Takaaki Tateishi <ttate@...>

Hello,

21 messages 2003/10/30
[#84787] Re: ruby-dev summary 21637-21729 — Paul Brannan <pbrannan@...> 2003/11/06

On Fri, Oct 31, 2003 at 07:01:28AM +0900, Takaaki Tateishi wrote:

[#84789] Re: ruby-dev summary 21637-21729 — matz@... (Yukihiro Matsumoto) 2003/11/06

Hi,

[#84792] Re: ruby-dev summary 21637-21729 — Paul Brannan <pbrannan@...> 2003/11/06

On Thu, Nov 06, 2003 at 11:17:59PM +0900, Yukihiro Matsumoto wrote:

[#84794] Re: ruby-dev summary 21637-21729 — matz@... (Yukihiro Matsumoto) 2003/11/06

Hi,

Re: bidirectional iterators, seeking advices

From: "Robert Klemme" <bob.news@...>
Date: 2003-10-01 15:21:33 UTC
List: ruby-talk #83348
"Simon Strandgaard" <qj5nd7l02@sneakemail.com> schrieb im Newsbeitrag
news:pan.2003.10.01.13.12.04.930935@sneakemail.com...
> The last 2 days I have been fooling around, making my own
> iterator hierarchy.
>
> question#1: any ideas if it makes sense not having a sentinel element?
>
> question#2: do you allways have it in the front?  or
> do you have it in both the front+back ?
>
> question#3: which implementation of iterators do you think is ideal?
> where do I have to look?   java, stl, python?

Dunno about Python, but I would only carefully use Java iterators as
model.  Though ListIterator is quite ok with respect to random access and
bidirectional iteration, they do not obey command query separation (i.e.
namely method next()).  C++ is better apart from the fact that I would not
use +, - etc. which you didn't.

IMHO C++ does a quite good job at separating the different aspects one
has:

 - iteration (forward, bidirectional, random access)
 - element access (read only, writable / deletable)

So in theory one could come up with 5 modules and combine them to classes.
Unfortunately one would not gain much by the modules other than the test
iter.kind_of? ModifyableIterator etc. because methods would have to be
implemented down the hierarchy... (This reminds me of the traits approach
that was referred to recently.  There was a paper about Traits for
Smalltalk.)

> suggestions for improving the code is very welcome :-)

I'm missing a most basic forward readonly iterator or did I overlook
something?

See further changes below

Regards

    robert


> --
> Simon Strandgaard
>
> server> ruby test_iterator.rb
> Loaded suite TestIterator
> Started
> .............F
> Finished in 0.019339 seconds.
>
>   1) Failure!!!
> test_reverse_range_each(TestIterator) [test_iterator.rb:136]:
> <[3, 2, 1]> expected but was
> <[2, 1, 0]>
>
> 14 tests, 16 assertions, 1 failures, 0 errors
> server> expand -t2 iterator.rb

class Iterator
   class Error < StandardError; end
   class NotComparable < Error; end

   def successor; nil end
   def has_successor?; false end

   def current; nil end

   def each
     first
     while has_successor?
       successor
       yield(current) # note: not self
     end
   end

  include Enumerable
end

class BidirectionalIterator < Iterator
  def predecessor; nil end
  def has_predecessor?; false end
end

module ModifiableIterator
  def current=(value); nil end
end

class RandomAccessIterator < BidirectionalIterator
  def first; nil ; end
  def last; nil ; end
  def set_position(pos); nil; end
end

> # purpose:
> # iterate over a collection (Array and similar classes)
> class CollectionIterator < BidirectionalIterator

  include ModifyableIterator

>   attr_reader :position
>   def initialize(data)
>     @data = data
>     first
>   end
>   def first
>     @position = -1 # a sentinel element
>   end
>   def successor
>     @position += 1
>   end
>   def has_successor?
>     @position < @data.size-1
>   end
>   def last
>     @position = @data.size  # a sentinel element
>   end
>   def predecessor
>     @position -= 1
>   end
>   def has_predecessor?
>     @position > 0
>   end
>   def current
>     @data[@position]
>   end
>   def current=(value)
>     @data[@position] = value
>   end
>   def <=>(other)
>     #raise NotComparable
>     @position <=> other.position
>   end
> end
>
> # purpose:
> # a decorator which reverses the direction of an iterator
> class ReverseIterator < BidirectionalIterator
>   def initialize(iterator); @i = iterator; end
>   def first; @i.last; end
>   def successor; @i.predecessor; end
>   def has_successor?; @i.has_predecessor?; end
>   def last; @i.first; end
>   def predecessor; @i.successor; end
>   def has_predecessor?; @i.has_successor?; end
>   def current; @i.current; end
>   def current=(value); @i.current = value; end
> end
>
> # purpose:
> # make one iterator out of to iterators
> #
> # first element is considered to be sentinel
> # and will therefore be ignored.
> class RangeIterator < BidirectionalIterator
>   def initialize(start, stop)
>     @start = start
>     @stop = stop
>     first
>   end
>   def first; @i = @start.clone end
>   def successor; @i.successor end
>   def has_successor?; @i < @stop end
>   def last; @i = @stop.clone end
>   def predecessor; @i.predecessor end
>   def has_predecessor?; @i > @start end
>   def current; @i.current; end
>   def current=(value); @i.current = value; end
> end
>
> class IteratorIterator < BidirectionalIterator
>   def initialize(iterators)
>     @iterators = iterators
>     first
>   end
>   def first
>     @position = 0
>     @iterators[@position].first
>   end
>   def successor
>     @iterators[@position].successor
>     unless @iterators[@position].has_successor?
>       @position += 1
>       @iterators[@position].first if has_successor?
>     end
>   end
>   def has_successor?
>     not (@position >= @iterators.size)
>   end
>   def current
>     @iterators[@position].current
>   end
>   def current=(value)
>     @iterators[@position].current = value
>   end
> end
>
> class Array
>   def create_iterator
>     CollectionIterator.new(self)
>   end
> end
> server> expand -t2 test_iterator.rb
> require 'test/unit'
> require 'iterator'
>
> class TestIterator < Test::Unit::TestCase
>   def test_base_notcomparable
>     i = BidirectionalIterator.new
>     assert_raises(BidirectionalIterator::NotComparable) { i > i }
>   end
>   def test_collection_compare
>     b = (0..8).to_a.create_iterator
>     b.successor # skip sentinel
>     b.successor
>     a = b.clone
>     b.successor
>     assert_equal([true, true, false], [a<b, a<=b, a==b])
>     a.successor
>     assert_equal([false, true, true], [a<b, a<=b, a==b])
>     a.successor
>     assert_equal([false, false, false], [a<b, a<=b, a==b])
>   end
>   def test_collection_has_successor
>     input = [-1, 0, 1, 2, 3]
>     exp = [true, true, true, false, false]
>     i = (0..2).to_a.create_iterator
>     i.first
>     class << i
>       attr_writer :position
>     end
>     res = input.map{|p| i.position=p; i.has_successor?}
>     assert_equal(exp, res)
>   end
>   def test_collection_has_predecessor
>     input = [-1, 0, 1, 2, 3]
>     exp = [false, false, true, true, true]
>     i = (0..2).to_a.create_iterator
>     i.last
>     class << i
>       attr_writer :position
>     end
>     res = input.map{|p| i.position=p; i.has_predecessor?}
>     assert_equal(exp, res)
>   end
>   def test_collection_successor_empty
>     iterator = [].create_iterator
>     iterator.first
>     assert_equal(false, iterator.has_successor?)
>   end
>   def test_collection_successor_elements
>     iterator = (1..5).to_a.create_iterator
>     res = []
>     iterator.first
>     while iterator.has_successor?
>       iterator.successor
>       res << iterator.current
>     end
>     assert_equal((1..5).to_a, res)
>   end
>   def test_collection_predecessor_elements
>     iterator = (1..5).to_a.create_iterator
>     res = []
>     iterator.last
>     while iterator.has_predecessor?
>       iterator.predecessor
>       res << iterator.current
>     end
>     assert_equal((1..5).to_a.reverse, res)
>   end
>   def test_collection_each
>     iterator = (1..5).to_a.create_iterator
>     ary = iterator.map{|i| i.current }
>     assert_equal((1..5).to_a, ary)
>   end
>   def test_collection_assignment
>     data = (1..5).to_a
>     iterator = data.create_iterator
>     iterator.successor # skip sentinel
>     iterator.successor
>     iterator.current = 5
>     assert_equal([1, 5, 3, 4, 5], data)
>   end
>   def test_collection_bidirectional
>     i = (0..2).to_a.create_iterator
>     i.first
>     i.successor # skip sentinel
>     res = []
>     res << i.current
>     i.successor
>     res << i.current
>     i.successor
>     res << i.current
>     res << i.has_successor?
>     i.predecessor
>     res << i.current
>     i.predecessor
>     res << i.current
>     res << i.has_predecessor?
>     assert_equal([0, 1, 2, false, 1, 0, false], res)
>   end
>   def test_reverse_each1
>     iterator = (1..5).to_a.create_iterator
>     ri = ReverseIterator.new(iterator)
>     ary = ri.map{|i| i.current }
>     assert_equal((1..5).to_a.reverse, ary)
>   end
>   def test_reverse_each2
>     iterator = (1..5).to_a.create_iterator
>     ri0 = ReverseIterator.new(iterator)
>     ri = ReverseIterator.new(ri0)
>     ary = ri.map{|i| i.current }
>     assert_equal((1..5).to_a, ary)
>   end
>   def test_range_each
>     data = (0..4).to_a
>     i = data.create_iterator
>     i.successor # skip sentinel
>     a = i.clone
>     i.successor
>     i.successor
>     i.successor
>     b = i.clone
>     iterator = RangeIterator.new(a, b)
>     res = iterator.map{|i| i.current}
>     assert_equal((1..3).to_a, res)
>   end
>   def test_reverse_range_each
>     data = (0..4).to_a
>     i = data.create_iterator
>     i.successor # skip sentinel
>     a = i.clone
>     i.successor
>     i.successor
>     i.successor
>     b = i.clone
>     iterator = ReverseIterator.new(RangeIterator.new(a, b))
>     res = iterator.map{|i| i.current}
>     assert_equal((1..3).to_a.reverse, res)
>   end
>   def xtest_iterator_iterator_each
>     i1 = (1..3).to_a.create_iterator
>     i2 = (5..7).to_a.create_iterator
>     iterator = IteratorIterator.new([i1, i2])
>     ary = iterator.map{|i| i.current }
>     assert_equal((1..3).to_a + (5..7).to_a, ary)
>   end
>   def xtest_iterator_iterator_assignment
>     data1 = (1..3).to_a
>     data2 = (5..7).to_a
>     i1 = data1.create_iterator
>     i2 = data2.create_iterator
>     iterator = IteratorIterator.new([i1, i2])
>     iterator.successor
>     iterator.current = 5
>     iterator.successor
>     iterator.successor
>     iterator.successor
>     iterator.current = 3
>     assert_equal([1, 5, 3, 5, 3, 7], data1 + data2)
>   end
> end
>
> if $0 == __FILE__
>   require 'test/unit/ui/console/testrunner'
>   Test::Unit::UI::Console::TestRunner.run(TestIterator)
> end
> server>


In This Thread

Prev Next