stream 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README ADDED
@@ -0,0 +1,174 @@
1
+ = Extended External Iterators (forward and backward)
2
+
3
+ == Description
4
+
5
+ Module Stream defines an interface for external iterators. A stream can be
6
+ seen as an iterator on a sequence of objects x1,...,xn. The state of the
7
+ stream is uniquely determined by the following methods:
8
+
9
+ * at_beginning?
10
+ * at_end?
11
+ * current
12
+ * peek
13
+
14
+ State changes are done with the following operations:
15
+
16
+ * set_to_begin
17
+ * set_to_end
18
+ * forward
19
+ * backward
20
+
21
+ With the help of the method current_edge the state of a stream s can be
22
+ exactly defined
23
+
24
+ s.current_edge == [s.current, s.peek]
25
+
26
+ If s a stream on [x1,...,xn]. Consider the edges [xi,xi+1] i=1,...,n and
27
+ [x0,x1] and [xn,xn+1] (x0 and xn are helper elements to define the boundary
28
+ conditions). Then if s is non empty, the following conditions must be true:
29
+
30
+ s.at_beginning? <=> s.current_edge == [x0,x1]
31
+ s.at_end? <=> s.current_edge == [xn,xn+1]
32
+ s.isEmpty? <=> s.at_beginning? && s.at_end? <=> s.current_edge == [x0,x1] <=> n = 0
33
+ s.set_to_end => s.at_end?
34
+ s.set_to_begin => s.at_beginning?
35
+
36
+ If 0 <= i < n and s.current_edge == [xi, xi+1] , then:
37
+
38
+ [s.forward, s.current_edge] == [xi+1, [xi+1, xi+2]]
39
+
40
+ If 1 <= i < n and s.current_edge == [xi, xi+1] , then:
41
+
42
+ [s.backward, s.current_edge] == [xi, [xi-1, xi]]
43
+
44
+ The result of peek is the same as of forward without changing state. The result of
45
+ current is the same as of backward without changing state.
46
+
47
+ Module Stream includes Enumerable implementing #each in the obvious way.
48
+
49
+ Not every stream needs to implement #backward and #at_beginning? thus being
50
+ not reversable. If they are reversable peek can easily be implemented using
51
+ forward and backward, as is done in module Stream. If a stream is not
52
+ reversable all derived streams provided by the stream module (filter,
53
+ mapping, concatenation) can be used anyway. Explicit or implicit (via peek or
54
+ current) uses of backward would throw a NotImplementedError.
55
+
56
+ Classes implementing the stream interface must implement the following methods:
57
+
58
+ * basic_forward
59
+ * basic_backward
60
+
61
+ * at_end?
62
+ * at_beginning?
63
+
64
+ The methods set_to_end and set_to_begin are by default implemented as:
65
+
66
+ set_to_end : until at_end?; do basic_forward end
67
+ set_to_begin : until at_beginning?; do basic_backward end
68
+
69
+ The methods forward and backward are by default implemented as:
70
+
71
+ forward: raise EndOfStreamException if at_end?; basic_forward.
72
+ backward: raise EndOfStreamException if at_beginning?; basic_backward
73
+
74
+ Thus subclasses must only implement *four* methods. Efficiency sometimes
75
+ demands better implementations.
76
+
77
+ There are several concrete classes implementing the stream interface:
78
+
79
+ * Stream::EmptyStream (boring)
80
+ * Stream::CollectionStream created by the method Array#create_stream
81
+ * Stream::FilteredStream created by the method Stream#filtered
82
+ * Stream::ReversedStream created by the method Stream#reverse
83
+ * Stream::ConcatenatedStream created by the method Stream#concatenate
84
+ * Stream::ImplicitStream using closures for the basic methods to implement
85
+
86
+ == Download
87
+
88
+ The latest version of stream.rb can be found at
89
+
90
+ * http://rubyforge.org/frs/?group_id=110
91
+
92
+ == Installation
93
+
94
+ === Normal Installation
95
+
96
+ You can install stream with the following command.
97
+
98
+ % ruby install.rb
99
+
100
+ from its distribution directory.
101
+
102
+ === GEM Installation
103
+
104
+ Download the GEM file and install it with ..
105
+
106
+ gem -i stream-VERSION.gem
107
+
108
+ Use the correct version number for VERSION (e.g. 0.5). You may need
109
+ root privileges to install.
110
+
111
+ == See also
112
+
113
+ * Streams in Smalltalk: http://wiki.cs.uiuc.edu/PatternStories/FunWithStreams
114
+ * Simon Strandgaards iterator.rb[http://aeditor.rubyforge.org/iterator/files/iterator_rb.html]
115
+ * IterationStyles: http://www.rubygarden.org/ruby?IterationStyles
116
+
117
+ == Examples
118
+
119
+ g = ('a'..'f').create_stream
120
+ h = (1..10).create_stream
121
+ i = (10..20).create_stream
122
+
123
+ until g.at_end? || h.at_end? || i.at_end?
124
+ p [g.forward, h.forward, i.forward]
125
+ end
126
+
127
+ def filestream fname
128
+ Stream::ImplicitStream.new { |s|
129
+ f = open(fname)
130
+ s.at_end_proc = proc {f.eof?}
131
+ s.forward_proc = proc {f.readline}
132
+ # Need not implement backward moving to use the framework
133
+ }
134
+ end
135
+
136
+ (filestream("/etc/passwd") + ('a'..'f').create_stream + filestream("/etc/group")).each do |l|
137
+ puts l
138
+ end
139
+
140
+ puts "\nTwo filtered collection streams concatenated and reversed:\n\n"
141
+
142
+ def newstream; (1..6).create_stream; end
143
+ s = newstream.filtered { |x| x % 2 == 0 } + newstream.filtered { |x| x % 2 != 0 }
144
+ s = s.reverse
145
+ puts "Contents : #{s.to_a.join ' '}"
146
+ puts "At end? : #{s.at_end?}"
147
+ puts "At beginning? : #{s.at_beginning?}"
148
+ puts "2xBackwards : #{s.backward} #{s.backward}"
149
+ puts "Forward : #{s.forward}"
150
+ puts "Peek : #{s.peek}"
151
+ puts "Current : #{s.current}"
152
+ puts "set_to_begin : Peek=#{s.set_to_begin;s.peek}"
153
+
154
+ # an infinite stream (do not use set_to_end!)
155
+ def randomStream
156
+ Stream::ImplicitStream.new { |s|
157
+ s.set_to_begin_proc = proc {srand 1234}
158
+ s.at_end_proc = proc {false}
159
+ s.forward_proc = proc {rand}
160
+ }
161
+ end
162
+ s = randomStream.filtered { |x| x >= 0.5 }.collect { |x| sprintf("%5.2f ",x*100) }
163
+ puts "5 random numbers: #{(1..5).collect {|x| s.forward}}\n" # =>
164
+
165
+ 5 random numbers: 74.05 94.80 87.87 86.07 83.70
166
+
167
+ == Other Stuff
168
+
169
+ $Revision: 1.1.1.1 $
170
+ $Date: 2004/05/13 23:30:03 $
171
+
172
+ Author:: Horst Duchene <hd.at.clr@hduchene.de>
173
+ License:: Copyright (c) 2001, 2004 Horst Duchene
174
+ Released under the same license as Ruby
@@ -0,0 +1,161 @@
1
+ # Rakefile for -*- ruby -*-
2
+
3
+ begin
4
+ require 'rubygems'
5
+ rescue Exception
6
+ nil
7
+ end
8
+ require 'rake/clean'
9
+ require 'rake/testtask'
10
+ require 'rake/gempackagetask'
11
+ require 'rake/rdoctask'
12
+
13
+ # Determine the current version of the software
14
+
15
+ if `ruby -Ilib -rstream -e'puts STREAM_VERSION'` =~ /\S+$/
16
+ PKG_VERSION = $&
17
+ else
18
+ PKG_VERSION = "0.0.0"
19
+ end
20
+
21
+ SRC_RB = FileList['lib/*.rb']
22
+
23
+ # The default task is run if rake is given no explicit arguments.
24
+
25
+ desc "Default Task"
26
+ task :default => :test
27
+
28
+ # Define a test task.
29
+
30
+ Rake::TestTask.new { |t|
31
+ #t.libs << "tests"
32
+ #t.pattern = 'tests/Test*.rb'
33
+ t.verbose = true
34
+ }
35
+
36
+ task :test
37
+
38
+ # Define a test that will run all the test targets.
39
+ desc "Run all test targets"
40
+ task :testall => [:test ]
41
+
42
+ # Install stream using the standard install.rb script.
43
+
44
+ desc "Install the application"
45
+ task :install do
46
+ ruby "install.rb"
47
+ end
48
+
49
+ # Create a task to build the RDOC documentation tree.
50
+
51
+ rd = Rake::RDocTask.new("rdoc") { |rdoc|
52
+ rdoc.rdoc_dir = 'html'
53
+ # rdoc.template = 'kilmer'
54
+ # rdoc.template = 'css2'
55
+ rdoc.title = "Stream - Extended External Iterators"
56
+ rdoc.options << '--line-numbers' << '--inline-source'
57
+ rdoc.rdoc_files.include('README')
58
+ rdoc.rdoc_files.include('lib/*.rb', 'doc/**/*.rdoc')
59
+ }
60
+
61
+ # ====================================================================
62
+ # Create a task that will package the stream software into distributable
63
+ # tar, zip and gem files.
64
+
65
+ PKG_FILES = FileList[
66
+ 'install.rb',
67
+ '[A-Z]*',
68
+ 'lib/**/*.rb',
69
+ 'test/**/*.rb',
70
+ 'examples/**/*'
71
+ ]
72
+
73
+ if ! defined?(Gem)
74
+ puts "Package Target requires RubyGEMs"
75
+ else
76
+ spec = Gem::Specification.new do |s|
77
+
78
+ #### Basic information.
79
+
80
+ s.name = 'stream'
81
+ s.version = PKG_VERSION
82
+ s.summary = "Stream - Extended External Iterators"
83
+ s.description = <<-EOF
84
+ Module Stream defines an interface for external iterators.
85
+ EOF
86
+
87
+ #### Dependencies and requirements.
88
+
89
+ #s.add_dependency('log4r', '> 1.0.4')
90
+ #s.requirements << ""
91
+
92
+ #### Which files are to be included in this gem? Everything! (Except CVS directories.)
93
+
94
+ s.files = PKG_FILES.to_a
95
+
96
+ #### C code extensions.
97
+
98
+ #s.extensions << "ext/rmagic/extconf.rb"
99
+
100
+ #### Load-time details: library and application (you will need one or both).
101
+
102
+ s.require_path = 'lib' # Use these for libraries.
103
+ s.autorequire = 'stream'
104
+
105
+ #### Documentation and testing.
106
+
107
+ s.has_rdoc = true
108
+ #s.test_suite_file = "test/rmagic-tests.rb"
109
+
110
+ #### Author and project details.
111
+ s.author = "Horst Duchene"
112
+ s.email = "hd.at.clr@hduchene.de"
113
+ s.homepage = "http://rgl.rubyforge.org"
114
+ s.rubyforge_project = "rgl"
115
+ end
116
+
117
+ Rake::GemPackageTask.new(spec) do |pkg|
118
+ pkg.need_zip = true
119
+ pkg.need_tar = true
120
+ end
121
+ end
122
+
123
+ # Misc tasks =========================================================
124
+
125
+ def count_lines(filename)
126
+ lines = 0
127
+ codelines = 0
128
+ open(filename) { |f|
129
+ f.each do |line|
130
+ lines += 1
131
+ next if line =~ /^\s*$/
132
+ next if line =~ /^\s*#/
133
+ codelines += 1
134
+ end
135
+ }
136
+ [lines, codelines]
137
+ end
138
+
139
+ def show_line(msg, lines, loc)
140
+ printf "%6s %6s %s\n", lines.to_s, loc.to_s, msg
141
+ end
142
+
143
+ desc "Count lines in the main files"
144
+ task :lines do
145
+ total_lines = 0
146
+ total_code = 0
147
+ show_line("File Name", "LINES", "LOC")
148
+ SRC_RB.each do |fn|
149
+ lines, codelines = count_lines(fn)
150
+ show_line(fn, lines, codelines)
151
+ total_lines += lines
152
+ total_code += codelines
153
+ end
154
+ show_line("TOTAL", total_lines, total_code)
155
+ end
156
+
157
+ ARCHIVEDIR = '/mnt/flash'
158
+
159
+ task :archive => [:package] do
160
+ cp FileList["pkg/*.tgz", "pkg/*.zip", "pkg/*.gem"], ARCHIVEDIR
161
+ end
@@ -0,0 +1,51 @@
1
+ require 'stream'
2
+
3
+ # Example from knu's Generator.rb
4
+ g = ('a'..'f').create_stream
5
+ h = (1..10).create_stream
6
+ i = (10..20).create_stream
7
+
8
+ until g.at_end? || h.at_end? || i.at_end?
9
+ p [g.forward, h.forward, i.forward]
10
+ end
11
+
12
+ puts "Concatenate Filestreams and collection stream:\n"
13
+
14
+ def fs fname
15
+ Stream::ImplicitStream.new { |s|
16
+ f = open(fname)
17
+ s.at_end_proc = proc {f.eof?}
18
+ s.forward_proc = proc {f.readline}
19
+ # Need not implement backward moving to use the framework
20
+ }
21
+ end
22
+
23
+ (fs("/etc/passwd") + ('a'..'f').create_stream + fs("/etc/group")).each do |l|
24
+ puts l
25
+ end
26
+
27
+ puts "\nTwo filtered collection streams concatenated and reversed:\n\n"
28
+
29
+ def newstream; (1..6).create_stream; end
30
+ s = newstream.filtered { |x| x % 2 == 0 } \
31
+ + newstream.filtered { |x| x % 2 != 0 }
32
+ s = s.reverse
33
+ puts "Contents : #{s.to_a.join ' '}"
34
+ puts "At end? : #{s.at_end?}"
35
+ puts "At beginning? : #{s.at_beginning?}"
36
+ puts "2xBackwards : #{s.backward} #{s.backward}"
37
+ puts "Forward : #{s.forward}"
38
+ puts "Peek : #{s.peek}"
39
+ puts "Current : #{s.current}"
40
+ puts "set_to_begin : Peek=#{s.set_to_begin;s.peek}"
41
+
42
+ # an infinite stream (do not use set_to_end!)
43
+ def randomStream
44
+ Stream::ImplicitStream.new { |s|
45
+ s.set_to_begin_proc = proc {srand 1234}
46
+ s.at_end_proc = proc {false}
47
+ s.forward_proc = proc {rand}
48
+ }
49
+ end
50
+ s = randomStream.filtered { |x| x >= 0.5 }.collect { |x| sprintf("%5.2f ",x*100) }
51
+ puts "5 random numbers: #{(1..5).collect {|x| s.forward}}\n"
@@ -0,0 +1,59 @@
1
+ #
2
+ # Simple stream test interface based on Ruby-FLTK
3
+ # See: (http://ruby-fltk.sourceforge.net/)
4
+ #
5
+ require 'fltk'
6
+ require 'stream'
7
+
8
+ class StreamTester < Fltk::Window
9
+ include Stream
10
+ def initialize (s)
11
+ super(200,200)
12
+ @stream = s
13
+
14
+ pack = Fltk::Pack.new(200,200) {
15
+ %w{set_to_begin set_to_end forward backward at_end? at_beginning? current_edge entries inspect}.each { |m|
16
+ Fltk::Button.new(50,20,m) {|w,data|
17
+ @output.value(sendMsg(m))
18
+ puts sendMsg(m)
19
+ }
20
+ }
21
+ @output= Fltk::Input.new(200, 20)
22
+ @output.deactivate
23
+ }
24
+ pack.packtype = Fltk::VERTICAL
25
+ self.add(pack)
26
+ self.show
27
+ end
28
+
29
+ def sendMsg(m)
30
+ begin
31
+ @stream.send(m).inspect
32
+ rescue EndOfStreamException => msg
33
+ msg
34
+ end
35
+ end
36
+ end
37
+
38
+ module Stream
39
+ def openTester
40
+ StreamTester.new(self)
41
+ Fltk::run()
42
+ end
43
+ end
44
+
45
+ if $0 == __FILE__
46
+ def newstream; (1..6).create_stream; end
47
+ s = newstream.filtered { |x| x % 2 == 0 } \
48
+ + newstream.filtered { |x| x % 2 != 0 }
49
+ s.reverse.openTester
50
+
51
+ # an infinite stream (do not use set_to_end!)
52
+ randomStream =
53
+ Stream::ImplicitStream.new { |s|
54
+ s.set_to_begin_proc = proc {srand 1234}
55
+ s.at_end_proc = proc {false}
56
+ s.forward_proc = proc {rand}
57
+ }
58
+ randomStream.filtered { |x| x >= 0.5 }.collect { |x| x*100 }.openTester
59
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rbconfig'
4
+ require 'ftools'
5
+ require 'find'
6
+
7
+ SRC_BASE = 'lib'
8
+ INSTDIR = File.join Config::CONFIG['sitedir']
9
+
10
+ def install
11
+ begin
12
+ pwd = Dir.pwd
13
+ Dir.chdir(SRC_BASE)
14
+ Dir['*.rb'].each do |file|
15
+ dst = File.join( INSTDIR, file )
16
+ File.install(file, dst, 0644, true)
17
+ end
18
+ Dir.chdir(pwd)
19
+ rescue
20
+ puts $!
21
+ end
22
+ end
23
+
24
+ install