functional 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/VERSION +1 -1
  2. data/lib/functional.rb +240 -17
  3. metadata +3 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.1
data/lib/functional.rb CHANGED
@@ -1,46 +1,269 @@
1
1
 
2
+ class ::Regexp
3
+ class NegRegexp
4
+ def initialize r
5
+ @rx = r
6
+ end
7
+ def match l
8
+ ! @rx.match( l)
9
+ end
10
+ def =~ l
11
+ ! @rx =~ l
12
+ end
13
+ def -@
14
+ @rx
15
+ end
16
+ end
17
+
18
+ def -@
19
+ NegRegexp.new self
20
+ end
21
+ end
22
+
23
+ class ::Object
24
+ def functional meth = nil
25
+ Functional.new self, meth
26
+ end
27
+ alias to_fun functional
28
+ end
29
+
2
30
  class Functional
3
31
  include Enumerable
4
32
 
5
- def self.method_missing meth, *args, &exe
6
- self.new.send meth, *args, &exe
33
+ class Base
34
+ attr_reader :exe
35
+ attr_accessor :next
36
+ def initialize &e
37
+ @exe = e
38
+ end
39
+
40
+ def call *a
41
+ @next.call *a
42
+ end
43
+
44
+ def end
45
+ @next.end
46
+ end
47
+
48
+ def to_proc
49
+ method( :call).to_proc
50
+ end
7
51
  end
8
52
 
9
- def push_method code, *args, &exe
10
- name = "__meth_#{exe.object_id}"
11
- define_singleton_method name, &exe
12
- @stack.push [code % name]+args
13
- self
53
+ class Collect <Base
54
+ def call *a
55
+ @next.call *@exe.call( *a)
56
+ end
57
+ end
58
+
59
+ class Select <Base
60
+ def call *a
61
+ @next.call *a if @exe.call *a
62
+ end
63
+ end
64
+
65
+ class DeleteIf <Base
66
+ def call *a
67
+ @next.call *a unless @exe.call *a
68
+ end
14
69
  end
15
70
 
71
+ class Compact <Base
72
+ def call *a
73
+ @next.call *a unless a.empty? || [nil] == a
74
+ end
75
+ end
76
+
77
+ class BottomUp <Base
78
+ def initialize start, *a, &e
79
+ @next.call *a, &e
80
+ @buffer, @start = nil, start
81
+ end
82
+
83
+ def call a
84
+ if @exe.call a
85
+ @next.call @buffer+a
86
+ @buffer = @start.dup
87
+ else
88
+ @buffer += a
89
+ end
90
+ end
91
+
92
+ def end
93
+ @next.call @buffer
94
+ @next.end
95
+ end
96
+ end
97
+
98
+ class TopDown <Base
99
+ def initialize start, *a, &e
100
+ @next.call *a, &e
101
+ @buffer, @start = nil, start
102
+ end
103
+
104
+ def call a
105
+ if @exe.call a
106
+ @next.call @buffer
107
+ @buffer = @start.dup+a
108
+ else
109
+ @buffer += a
110
+ end
111
+ end
112
+
113
+ def end
114
+ @next.call @buffer
115
+ @next.end
116
+ end
117
+ end
118
+
119
+ class Each <Base
120
+ def end
121
+ nil
122
+ end
123
+ end
124
+
125
+ class P <Each
126
+ def initialize *a
127
+ super *a, &Kernel.method( :p)
128
+ end
129
+ end
130
+
131
+ class Inject <Base
132
+ attr_reader :it
133
+ def initialize start, *a, &e
134
+ super *a, &e
135
+ @it = start
136
+ end
137
+ def call *a
138
+ @it = @exe.call @it, *a
139
+ end
140
+ def end
141
+ @it
142
+ end
143
+ end
144
+
145
+ class To_a <Inject
146
+ def initialize *a, &e
147
+ super [], *a, &e
148
+ end
149
+ end
150
+
151
+ class Map <Collect
152
+ def call *a
153
+ @exe.call *a, &@next
154
+ end
155
+ end
156
+
157
+ class Reduce <Base
158
+ def initialize iv, *a, &e
159
+ super *a, &e
160
+ @buf = {}
161
+ @buf.default = iv
162
+ end
163
+
164
+ def call *a
165
+ @buf[ a[0]] = @exe.call @buf[ a[0]], *a[1..-1]
166
+ end
167
+
168
+ def end
169
+ @buf.each {|i| @next.call *i}
170
+ @next.end
171
+ end
172
+ end
173
+
174
+ attr_accessor :next, :stack, :obj, :func, :args
175
+
16
176
  def initialize obj = nil, func = nil, *args
17
- @stack, @obj, @func, @args = [], obj, func, args
177
+ @next, @stack, @obj, @func, @args = self, self, obj, func, args
178
+ end
179
+
180
+ def push a
181
+ @stack = @stack.next = a
182
+ self
18
183
  end
19
184
 
20
185
  def collect &exe
21
- push_method "value=%s(value)", &exe
186
+ push Collect.new( &exe)
22
187
  end
23
188
 
24
- # map/reduce?
25
189
  def map &exe
26
- raise "Reserved for MapReduce."
190
+ push Map.new( &exe)
27
191
  end
28
192
 
29
- # map/reduce?
30
- def reduce &exe
31
- raise "Reserved for MapReduce."
193
+ def reduce iv, &exe
194
+ push Reduce.new( iv, &exe)
32
195
  end
33
196
 
34
197
  def select &exe
35
- push_method "%s(value)||next", &exe
198
+ push Select.new( &exe)
199
+ end
200
+
201
+ def grep re
202
+ push Select.new( &re.method( :match))
36
203
  end
37
204
 
38
205
  def delete_if &exe
39
- push_method "%s(value)&&next", &exe
206
+ push DeleteIf.new( &exe)
207
+ end
208
+
209
+ def compact
210
+ push Compact.new
211
+ end
212
+
213
+ def updown init, &exe
214
+ push UpDown.new( init, &exe)
215
+ end
216
+
217
+ def topdown init, &exe
218
+ push TopDown.new( init, &exe)
40
219
  end
41
220
 
42
221
  def each &exe
43
222
  return self unless exe
44
- @obj.send @func || :each, *@args, &eval( "lambda{|value|#{@stack.join( ";")};exe.call(value)}")
223
+ push Each.new
224
+ push exe
225
+ run
226
+ end
227
+
228
+ def join deli
229
+ push Inject.new('') {|i,j|i+deli+j}
230
+ run
231
+ end
232
+
233
+ def run
234
+ @obj.send @func||:each, *@args, &@next #.method(:call)
235
+ @next.end
236
+ end
237
+
238
+ def p
239
+ each {|*a|Kernel.p a}
45
240
  end
46
241
  end
242
+
243
+ begin
244
+ require 'tokyocabinet'
245
+
246
+ class Functional
247
+ class Map <Base
248
+ class Emit < TokyoCabinet::BDB
249
+ alias emit putdup
250
+ alias call emit
251
+ end
252
+
253
+ def call *a
254
+ @exe.call( *a).each &@next
255
+ end
256
+ end
257
+
258
+ def map name, &e
259
+ push Map.new( name, &e)
260
+ end
261
+
262
+ def Reduce name, &e
263
+ push Reduce.new( name, &e)
264
+ end
265
+ end
266
+
267
+ rescue MissingSourceFile
268
+ # TokyoCabinet not installed?
269
+ end if false
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 0
8
7
  - 1
9
- version: 0.0.1
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Denis Knauf
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-19 00:00:00 +02:00
17
+ date: 2010-05-25 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies: []
20
20