totally_lazy 0.0.20 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/compiler.xml +22 -0
- data/.idea/encodings.xml +6 -0
- data/.idea/misc.xml +19 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.travis.yml +2 -5
- data/Gemfile +6 -8
- data/Guardfile +2 -17
- data/LICENSE +202 -0
- data/Rakefile +18 -33
- data/VERSION +1 -1
- data/contributors.txt +1 -0
- data/lib/comparators.rb +9 -0
- data/lib/enumerators.rb +74 -0
- data/lib/functions.rb +66 -0
- data/lib/numbers.rb +38 -0
- data/lib/option.rb +38 -268
- data/lib/pair.rb +13 -51
- data/lib/predicates.rb +5 -0
- data/lib/sequence.rb +171 -526
- data/lib/strings.rb +13 -0
- data/lib/totally_lazy.rb +14 -165
- data/readme.md +2 -0
- data/spec/option_spec.rb +6 -182
- data/spec/sequence_spec.rb +202 -132
- data/spec/spec_helper.rb +0 -13
- data/totally_lazy.iml +74 -0
- metadata +58 -71
- data/.document +0 -5
- data/.rspec +0 -1
- data/LICENSE.txt +0 -20
- data/README.md +0 -173
- data/lib/any.rb +0 -13
- data/lib/functor.rb +0 -92
- data/lib/generators.rb +0 -161
- data/lib/parallel/parallel.rb +0 -442
- data/lib/parallel/processor_count.rb +0 -85
- data/lib/predicates/compare.rb +0 -25
- data/lib/predicates/conversions.rb +0 -22
- data/lib/predicates/numbers.rb +0 -21
- data/lib/predicates/predicates.rb +0 -141
- data/lib/predicates/where.rb +0 -34
- data/lib/predicates/where_processor.rb +0 -13
- data/lib/type_check.rb +0 -19
- data/lib/utils.rb +0 -9
- data/spec/functor_spec.rb +0 -35
- data/spec/generators_spec.rb +0 -37
- data/spec/pair_spec.rb +0 -44
- data/spec/predicate_spec.rb +0 -77
- data/spec/serialization_spec.rb +0 -56
- data/spec/type_check_spec.rb +0 -20
- data/spec/util_spec.rb +0 -10
- data/totally_lazy.gemspec +0 -101
data/lib/parallel/parallel.rb
DELETED
@@ -1,442 +0,0 @@
|
|
1
|
-
require 'rbconfig'
|
2
|
-
require_relative 'processor_count'
|
3
|
-
|
4
|
-
module Parallel
|
5
|
-
extend Parallel::ProcessorCount
|
6
|
-
|
7
|
-
class DeadWorker < StandardError
|
8
|
-
end
|
9
|
-
|
10
|
-
class Break < StandardError
|
11
|
-
end
|
12
|
-
|
13
|
-
class Kill < StandardError
|
14
|
-
end
|
15
|
-
|
16
|
-
Stop = Object.new
|
17
|
-
|
18
|
-
INTERRUPT_SIGNAL = :SIGINT
|
19
|
-
|
20
|
-
class ExceptionWrapper
|
21
|
-
attr_reader :exception
|
22
|
-
def initialize(exception)
|
23
|
-
dumpable = Marshal.dump(exception) rescue nil
|
24
|
-
unless dumpable
|
25
|
-
exception = RuntimeError.new("Undumpable Exception -- #{exception.inspect}")
|
26
|
-
end
|
27
|
-
|
28
|
-
@exception = exception
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class Worker
|
33
|
-
attr_reader :pid, :read, :write
|
34
|
-
attr_accessor :thread
|
35
|
-
def initialize(read, write, pid)
|
36
|
-
@read, @write, @pid = read, write, pid
|
37
|
-
end
|
38
|
-
|
39
|
-
def close_pipes
|
40
|
-
read.close
|
41
|
-
write.close
|
42
|
-
end
|
43
|
-
|
44
|
-
def wait
|
45
|
-
Process.wait(pid)
|
46
|
-
rescue Interrupt
|
47
|
-
# process died
|
48
|
-
end
|
49
|
-
|
50
|
-
def work(data)
|
51
|
-
begin
|
52
|
-
Marshal.dump(data, write)
|
53
|
-
rescue Errno::EPIPE
|
54
|
-
raise DeadWorker
|
55
|
-
end
|
56
|
-
|
57
|
-
begin
|
58
|
-
Marshal.load(read)
|
59
|
-
rescue EOFError
|
60
|
-
raise DeadWorker
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class ItemWrapper
|
66
|
-
def initialize(array, mutex)
|
67
|
-
@lambda = (array.respond_to?(:call) && array) || queue_wrapper(array)
|
68
|
-
@items = array.to_a unless @lambda # turn Range and other Enumerable-s into an Array
|
69
|
-
@mutex = mutex
|
70
|
-
@index = -1
|
71
|
-
end
|
72
|
-
|
73
|
-
def producer?
|
74
|
-
@lambda
|
75
|
-
end
|
76
|
-
|
77
|
-
def each_with_index(&block)
|
78
|
-
if producer?
|
79
|
-
loop do
|
80
|
-
item, index = self.next
|
81
|
-
break unless index
|
82
|
-
yield(item, index)
|
83
|
-
end
|
84
|
-
else
|
85
|
-
@items.each_with_index(&block)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def next
|
90
|
-
if producer?
|
91
|
-
# - index and item stay in sync
|
92
|
-
# - do not call lambda after it has returned Stop
|
93
|
-
item, index = @mutex.synchronize do
|
94
|
-
return if @stopped
|
95
|
-
item = @lambda.call
|
96
|
-
@stopped = (item == Parallel::Stop)
|
97
|
-
return if @stopped
|
98
|
-
[item, @index += 1]
|
99
|
-
end
|
100
|
-
else
|
101
|
-
index = @mutex.synchronize { @index += 1 }
|
102
|
-
return if index >= size
|
103
|
-
item = @items[index]
|
104
|
-
end
|
105
|
-
[item, index]
|
106
|
-
end
|
107
|
-
|
108
|
-
def size
|
109
|
-
@items.size
|
110
|
-
end
|
111
|
-
|
112
|
-
def pack(item, index)
|
113
|
-
producer? ? [item, index] : index
|
114
|
-
end
|
115
|
-
|
116
|
-
def unpack(data)
|
117
|
-
producer? ? data : [@items[data], data]
|
118
|
-
end
|
119
|
-
|
120
|
-
def queue_wrapper(array)
|
121
|
-
array.respond_to?(:num_waiting) && array.respond_to?(:pop) && lambda { array.pop(false) }
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
class << self
|
126
|
-
def in_threads(options={:count => 2})
|
127
|
-
count, options = extract_count_from_options(options)
|
128
|
-
|
129
|
-
out = []
|
130
|
-
threads = []
|
131
|
-
|
132
|
-
count.times do |i|
|
133
|
-
threads[i] = Thread.new do
|
134
|
-
out[i] = yield(i)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
kill_on_ctrl_c(threads) { wait_for_threads(threads) }
|
139
|
-
|
140
|
-
out
|
141
|
-
end
|
142
|
-
|
143
|
-
def in_processes(options = {}, &block)
|
144
|
-
count, options = extract_count_from_options(options)
|
145
|
-
count ||= processor_count
|
146
|
-
map(0...count, options.merge(:in_processes => count), &block)
|
147
|
-
end
|
148
|
-
|
149
|
-
def each(array, options={}, &block)
|
150
|
-
map(array, options.merge(:preserve_results => false), &block)
|
151
|
-
array
|
152
|
-
end
|
153
|
-
|
154
|
-
def each_with_index(array, options={}, &block)
|
155
|
-
each(array, options.merge(:with_index => true), &block)
|
156
|
-
end
|
157
|
-
|
158
|
-
def map(array, options = {}, &block)
|
159
|
-
options[:mutex] = Mutex.new
|
160
|
-
|
161
|
-
if RUBY_PLATFORM =~ /java/ and not options[:in_processes]
|
162
|
-
method = :in_threads
|
163
|
-
size = options[method] || processor_count
|
164
|
-
elsif options[:in_threads]
|
165
|
-
method = :in_threads
|
166
|
-
size = options[method]
|
167
|
-
else
|
168
|
-
method = :in_processes
|
169
|
-
if Process.respond_to?(:fork)
|
170
|
-
size = options[method] || processor_count
|
171
|
-
else
|
172
|
-
$stderr.puts "Warning: Process.fork is not supported by this Ruby"
|
173
|
-
size = 0
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
items = ItemWrapper.new(array, options[:mutex])
|
178
|
-
|
179
|
-
size = [items.producer? ? size : items.size, size].min
|
180
|
-
|
181
|
-
options[:return_results] = (options[:preserve_results] != false || !!options[:finish])
|
182
|
-
add_progress_bar!(items, options)
|
183
|
-
|
184
|
-
if size == 0
|
185
|
-
work_direct(items, options, &block)
|
186
|
-
elsif method == :in_threads
|
187
|
-
work_in_threads(items, options.merge(:count => size), &block)
|
188
|
-
else
|
189
|
-
work_in_processes(items, options.merge(:count => size), &block)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def map_with_index(array, options={}, &block)
|
194
|
-
map(array, options.merge(:with_index => true), &block)
|
195
|
-
end
|
196
|
-
|
197
|
-
private
|
198
|
-
|
199
|
-
def add_progress_bar!(items, options)
|
200
|
-
if title = options[:progress]
|
201
|
-
raise "Progressbar and producers don't mix" if items.producer?
|
202
|
-
require 'ruby-progressbar'
|
203
|
-
progress = ProgressBar.create(
|
204
|
-
:title => title,
|
205
|
-
:total => items.size,
|
206
|
-
:format => '%t |%E | %B | %a'
|
207
|
-
)
|
208
|
-
old_finish = options[:finish]
|
209
|
-
options[:finish] = lambda do |item, i, result|
|
210
|
-
old_finish.call(item, i, result) if old_finish
|
211
|
-
progress.increment
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
|
217
|
-
def work_direct(items, options)
|
218
|
-
results = []
|
219
|
-
items.each_with_index do |e,i|
|
220
|
-
results << (options[:with_index] ? yield(e,i) : yield(e))
|
221
|
-
end
|
222
|
-
results
|
223
|
-
end
|
224
|
-
|
225
|
-
def work_in_threads(items, options, &block)
|
226
|
-
results = []
|
227
|
-
exception = nil
|
228
|
-
|
229
|
-
in_threads(options[:count]) do
|
230
|
-
# as long as there are more items, work on one of them
|
231
|
-
loop do
|
232
|
-
break if exception
|
233
|
-
item, index = items.next
|
234
|
-
break unless index
|
235
|
-
|
236
|
-
begin
|
237
|
-
results[index] = with_instrumentation item, index, options do
|
238
|
-
call_with_index(item, index, options, &block)
|
239
|
-
end
|
240
|
-
rescue StandardError => e
|
241
|
-
exception = e
|
242
|
-
break
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
handle_exception(exception, results)
|
248
|
-
end
|
249
|
-
|
250
|
-
def work_in_processes(items, options, &blk)
|
251
|
-
workers = create_workers(items, options, &blk)
|
252
|
-
results = []
|
253
|
-
exception = nil
|
254
|
-
|
255
|
-
kill_on_ctrl_c(workers.map(&:pid)) do
|
256
|
-
in_threads(options[:count]) do |i|
|
257
|
-
worker = workers[i]
|
258
|
-
worker.thread = Thread.current
|
259
|
-
|
260
|
-
begin
|
261
|
-
loop do
|
262
|
-
break if exception
|
263
|
-
item, index = items.next
|
264
|
-
break unless index
|
265
|
-
|
266
|
-
output = with_instrumentation item, index, options do
|
267
|
-
worker.work(items.pack(item, index))
|
268
|
-
end
|
269
|
-
|
270
|
-
if ExceptionWrapper === output
|
271
|
-
exception = output.exception
|
272
|
-
if Parallel::Kill === exception
|
273
|
-
(workers - [worker]).each do |w|
|
274
|
-
kill_that_thing!(w.thread)
|
275
|
-
kill_that_thing!(w.pid)
|
276
|
-
end
|
277
|
-
end
|
278
|
-
else
|
279
|
-
results[index] = output
|
280
|
-
end
|
281
|
-
end
|
282
|
-
ensure
|
283
|
-
worker.close_pipes
|
284
|
-
worker.wait # if it goes zombie, rather wait here to be able to debug
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
handle_exception(exception, results)
|
290
|
-
end
|
291
|
-
|
292
|
-
def create_workers(items, options, &block)
|
293
|
-
workers = []
|
294
|
-
Array.new(options[:count]).each do
|
295
|
-
workers << worker(items, options.merge(:started_workers => workers), &block)
|
296
|
-
end
|
297
|
-
workers
|
298
|
-
end
|
299
|
-
|
300
|
-
def worker(items, options, &block)
|
301
|
-
# use less memory on REE
|
302
|
-
GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=)
|
303
|
-
|
304
|
-
child_read, parent_write = IO.pipe
|
305
|
-
parent_read, child_write = IO.pipe
|
306
|
-
|
307
|
-
pid = Process.fork do
|
308
|
-
begin
|
309
|
-
options.delete(:started_workers).each(&:close_pipes)
|
310
|
-
|
311
|
-
parent_write.close
|
312
|
-
parent_read.close
|
313
|
-
|
314
|
-
process_incoming_jobs(child_read, child_write, items, options, &block)
|
315
|
-
ensure
|
316
|
-
child_read.close
|
317
|
-
child_write.close
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
child_read.close
|
322
|
-
child_write.close
|
323
|
-
|
324
|
-
Worker.new(parent_read, parent_write, pid)
|
325
|
-
end
|
326
|
-
|
327
|
-
def process_incoming_jobs(read, write, items, options, &block)
|
328
|
-
while !read.eof?
|
329
|
-
data = Marshal.load(read)
|
330
|
-
item, index = items.unpack(data)
|
331
|
-
result = begin
|
332
|
-
call_with_index(item, index, options, &block)
|
333
|
-
rescue StandardError => e
|
334
|
-
ExceptionWrapper.new(e)
|
335
|
-
end
|
336
|
-
Marshal.dump(result, write)
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
def wait_for_threads(threads)
|
341
|
-
interrupted = threads.compact.map do |t|
|
342
|
-
begin
|
343
|
-
t.join
|
344
|
-
nil
|
345
|
-
rescue Interrupt => e
|
346
|
-
e # thread died, do not stop other threads
|
347
|
-
end
|
348
|
-
end.compact
|
349
|
-
raise interrupted.first if interrupted.first
|
350
|
-
end
|
351
|
-
|
352
|
-
def handle_exception(exception, results)
|
353
|
-
return nil if [Parallel::Break, Parallel::Kill].include? exception.class
|
354
|
-
raise exception if exception
|
355
|
-
results
|
356
|
-
end
|
357
|
-
|
358
|
-
# options is either a Integer or a Hash with :count
|
359
|
-
def extract_count_from_options(options)
|
360
|
-
if options.is_a?(Hash)
|
361
|
-
count = options[:count]
|
362
|
-
else
|
363
|
-
count = options
|
364
|
-
options = {}
|
365
|
-
end
|
366
|
-
[count, options]
|
367
|
-
end
|
368
|
-
|
369
|
-
# kill all these pids or threads if user presses Ctrl+c
|
370
|
-
def kill_on_ctrl_c(things)
|
371
|
-
@to_be_killed ||= []
|
372
|
-
old_interrupt = nil
|
373
|
-
|
374
|
-
if @to_be_killed.empty?
|
375
|
-
old_interrupt = trap_interrupt do
|
376
|
-
$stderr.puts 'Parallel execution interrupted, exiting ...'
|
377
|
-
@to_be_killed.flatten.compact.each { |thing| kill_that_thing!(thing) }
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
@to_be_killed << things
|
382
|
-
|
383
|
-
yield
|
384
|
-
ensure
|
385
|
-
@to_be_killed.pop # free threads for GC and do not kill pids that could be used for new processes
|
386
|
-
restore_interrupt(old_interrupt) if @to_be_killed.empty?
|
387
|
-
end
|
388
|
-
|
389
|
-
def trap_interrupt
|
390
|
-
old = Signal.trap INTERRUPT_SIGNAL, 'IGNORE'
|
391
|
-
|
392
|
-
Signal.trap INTERRUPT_SIGNAL do
|
393
|
-
yield
|
394
|
-
if old == "DEFAULT"
|
395
|
-
raise Interrupt
|
396
|
-
else
|
397
|
-
old.call
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
old
|
402
|
-
end
|
403
|
-
|
404
|
-
def restore_interrupt(old)
|
405
|
-
Signal.trap INTERRUPT_SIGNAL, old
|
406
|
-
end
|
407
|
-
|
408
|
-
def kill_that_thing!(thing)
|
409
|
-
if thing.is_a?(Thread)
|
410
|
-
thing.kill
|
411
|
-
else
|
412
|
-
begin
|
413
|
-
Process.kill(:KILL, thing)
|
414
|
-
rescue Errno::ESRCH
|
415
|
-
# some linux systems already automatically killed the children at this point
|
416
|
-
# so we just ignore them not being there
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
def call_with_index(item, index, options, &block)
|
422
|
-
args = [item]
|
423
|
-
args << index if options[:with_index]
|
424
|
-
if options[:return_results]
|
425
|
-
block.call(*args)
|
426
|
-
else
|
427
|
-
block.call(*args)
|
428
|
-
nil # avoid GC overhead of passing large results around
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
def with_instrumentation(item, index, options)
|
433
|
-
on_start = options[:start]
|
434
|
-
on_finish = options[:finish]
|
435
|
-
options[:mutex].synchronize { on_start.call(item, index) } if on_start
|
436
|
-
result = yield
|
437
|
-
result unless options[:preserve_results] == false
|
438
|
-
ensure
|
439
|
-
options[:mutex].synchronize { on_finish.call(item, index, result) } if on_finish
|
440
|
-
end
|
441
|
-
end
|
442
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
module Parallel
|
2
|
-
module ProcessorCount
|
3
|
-
# Number of processors seen by the OS and used for process scheduling.
|
4
|
-
#
|
5
|
-
# * AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
|
6
|
-
# * BSD: /sbin/sysctl
|
7
|
-
# * Cygwin: /proc/cpuinfo
|
8
|
-
# * Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
|
9
|
-
# * HP-UX: /usr/sbin/ioscan
|
10
|
-
# * IRIX: /usr/sbin/sysconf
|
11
|
-
# * Linux: /proc/cpuinfo
|
12
|
-
# * Minix 3+: /proc/cpuinfo
|
13
|
-
# * Solaris: /usr/sbin/psrinfo
|
14
|
-
# * Tru64 UNIX: /usr/sbin/psrinfo
|
15
|
-
# * UnixWare: /usr/sbin/psrinfo
|
16
|
-
#
|
17
|
-
def processor_count
|
18
|
-
@processor_count ||= begin
|
19
|
-
os_name = RbConfig::CONFIG["target_os"]
|
20
|
-
if os_name =~ /mingw|mswin/
|
21
|
-
require 'win32ole'
|
22
|
-
result = WIN32OLE.connect("winmgmts://").ExecQuery(
|
23
|
-
"select NumberOfLogicalProcessors from Win32_Processor")
|
24
|
-
result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+)
|
25
|
-
elsif File.readable?("/proc/cpuinfo")
|
26
|
-
IO.read("/proc/cpuinfo").scan(/^processor/).size
|
27
|
-
elsif File.executable?("/usr/bin/hwprefs")
|
28
|
-
IO.popen("/usr/bin/hwprefs thread_count").read.to_i
|
29
|
-
elsif File.executable?("/usr/sbin/psrinfo")
|
30
|
-
IO.popen("/usr/sbin/psrinfo").read.scan(/^.*on-*line/).size
|
31
|
-
elsif File.executable?("/usr/sbin/ioscan")
|
32
|
-
IO.popen("/usr/sbin/ioscan -kC processor") do |out|
|
33
|
-
out.read.scan(/^.*processor/).size
|
34
|
-
end
|
35
|
-
elsif File.executable?("/usr/sbin/pmcycles")
|
36
|
-
IO.popen("/usr/sbin/pmcycles -m").read.count("\n")
|
37
|
-
elsif File.executable?("/usr/sbin/lsdev")
|
38
|
-
IO.popen("/usr/sbin/lsdev -Cc processor -S 1").read.count("\n")
|
39
|
-
elsif File.executable?("/usr/sbin/sysconf") and os_name =~ /irix/i
|
40
|
-
IO.popen("/usr/sbin/sysconf NPROC_ONLN").read.to_i
|
41
|
-
elsif File.executable?("/usr/sbin/sysctl")
|
42
|
-
IO.popen("/usr/sbin/sysctl -n hw.ncpu").read.to_i
|
43
|
-
elsif File.executable?("/sbin/sysctl")
|
44
|
-
IO.popen("/sbin/sysctl -n hw.ncpu").read.to_i
|
45
|
-
else
|
46
|
-
$stderr.puts "Unknown platform: " + RbConfig::CONFIG["target_os"]
|
47
|
-
$stderr.puts "Assuming 1 processor."
|
48
|
-
1
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Number of physical processor cores on the current system.
|
54
|
-
#
|
55
|
-
def physical_processor_count
|
56
|
-
@physical_processor_count ||= begin
|
57
|
-
ppc = case RbConfig::CONFIG["target_os"]
|
58
|
-
when /darwin1/
|
59
|
-
IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i
|
60
|
-
when /linux/
|
61
|
-
cores = {} # unique physical ID / core ID combinations
|
62
|
-
phy = 0
|
63
|
-
IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
|
64
|
-
if ln.start_with?("physical")
|
65
|
-
phy = ln[/\d+/]
|
66
|
-
elsif ln.start_with?("core")
|
67
|
-
cid = phy + ":" + ln[/\d+/]
|
68
|
-
cores[cid] = true if not cores[cid]
|
69
|
-
end
|
70
|
-
end
|
71
|
-
cores.count
|
72
|
-
when /mswin|mingw/
|
73
|
-
require 'win32ole'
|
74
|
-
result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
|
75
|
-
"select NumberOfCores from Win32_Processor")
|
76
|
-
result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
|
77
|
-
else
|
78
|
-
processor_count
|
79
|
-
end
|
80
|
-
# fall back to logical count if physical info is invalid
|
81
|
-
ppc > 0 ? ppc : processor_count
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/lib/predicates/compare.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Predicates
|
2
|
-
|
3
|
-
module Compare
|
4
|
-
|
5
|
-
def equals(value)
|
6
|
-
value_predicate(:equals,:==,value)
|
7
|
-
end
|
8
|
-
|
9
|
-
alias equal_to equals
|
10
|
-
|
11
|
-
def greater_than(value)
|
12
|
-
value_predicate(:greater_than,:>,value)
|
13
|
-
end
|
14
|
-
|
15
|
-
def less_than(value)
|
16
|
-
value_predicate(:less_than,:<,value)
|
17
|
-
end
|
18
|
-
|
19
|
-
def matches(value)
|
20
|
-
regex_predicate(:matches,value)
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Predicates
|
2
|
-
|
3
|
-
module Conversions
|
4
|
-
|
5
|
-
def as_string
|
6
|
-
simple_transform(:as_string, -> (v) { v.to_s } )
|
7
|
-
end
|
8
|
-
|
9
|
-
def as_int
|
10
|
-
simple_transform(:as_int, -> (v) { Type.responds(v, :to_i); v.to_i } )
|
11
|
-
end
|
12
|
-
|
13
|
-
def as_float
|
14
|
-
simple_transform(:as_float, -> (v) { Type.responds(v, :to_f); v.to_f } )
|
15
|
-
end
|
16
|
-
|
17
|
-
def as_array
|
18
|
-
simple_transform(:as_array, -> (v) { [v] } )
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
data/lib/predicates/numbers.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module Predicates
|
2
|
-
|
3
|
-
module Numbers
|
4
|
-
|
5
|
-
def even
|
6
|
-
self_predicate(:even,:even?)
|
7
|
-
end
|
8
|
-
|
9
|
-
def odd
|
10
|
-
self_predicate(:odd,:odd?)
|
11
|
-
end
|
12
|
-
#
|
13
|
-
# def between(lower, higher)
|
14
|
-
# -> (v, meth=:self, invert=false) do
|
15
|
-
# invert ? inverted(v, meth, :between?) : regular(v, meth, :between?)
|
16
|
-
# end
|
17
|
-
# end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|