LazyEnumerable 0.0.3 → 0.0.4
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/lib/lazy/extensions.rb +1 -1
- data/lib/lazy/lazy_enumerable.rb +102 -78
- data/lib/lazy_enumerable.rb +1 -6
- metadata +2 -7
- data/lib/lazy/abstract_enumerable.rb +0 -50
- data/lib/lazy/collect_enumerable.rb +0 -14
- data/lib/lazy/message_collector.rb +0 -68
- data/lib/lazy/reject_enumerable.rb +0 -14
- data/lib/lazy/select_enumerable.rb +0 -14
data/lib/lazy/extensions.rb
CHANGED
data/lib/lazy/lazy_enumerable.rb
CHANGED
@@ -1,79 +1,103 @@
|
|
1
|
-
###
|
2
|
-
###
|
3
|
-
###
|
4
|
-
###
|
5
|
-
###
|
6
|
-
###
|
7
|
-
###
|
8
|
-
###
|
9
|
-
###
|
10
|
-
###
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
##
|
18
|
-
##
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def self.
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
##
|
52
|
-
##
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
1
|
+
###
|
2
|
+
### LazyEnumerable makes the implementation of higher order methods easier. LazyIterator
|
3
|
+
### is a simple implemetation of that. It basically works by "stacking" up the method
|
4
|
+
### calls until the collection needs to be calculated (realized). It then calls the
|
5
|
+
### "stacked up" methods.
|
6
|
+
###
|
7
|
+
### LazyEnumerable is immutable and I would like LazyIterator to be as well. But,
|
8
|
+
### every attempt has made the code ugly and inelegant. I'm still looking for a good
|
9
|
+
### solution. Immuntability gives the ability to calculate on different levels.
|
10
|
+
###
|
11
|
+
module Lazy
|
12
|
+
|
13
|
+
class LazyEnumerable
|
14
|
+
PLACEBO=lambda {|each| each}
|
15
|
+
|
16
|
+
##
|
17
|
+
## Remove any unnecessary methods so that method_missing is invoked
|
18
|
+
##
|
19
|
+
def self.wack_all_my_methods
|
20
|
+
to_wack = instance_methods.reject do |each|
|
21
|
+
['===','method_missing'].include?(each) || each =~ /^__/
|
22
|
+
end
|
23
|
+
to_wack.each do |each|
|
24
|
+
alias_method("_#{each}", each)
|
25
|
+
undef_method(each)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.iterator_creator(*method_names)
|
30
|
+
method_names.each { |every| iterator_creator_for(every) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.iterator_creator_for(method_name)
|
34
|
+
non_lazy_name = /lazy_(.+)/.match(method_name.to_s)[1].to_sym
|
35
|
+
define_method(method_name) { LazyEnumerable.new(_method(non_lazy_name)) }
|
36
|
+
end
|
37
|
+
|
38
|
+
wack_all_my_methods
|
39
|
+
include Enumerable
|
40
|
+
iterator_creator :lazy_inject, :lazy_select, :lazy_collect, :lazy_reject, :lazy_detect, :lazy_each
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
def initialize(proc)
|
45
|
+
@internal=proc
|
46
|
+
@sends=[]
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
## Simply make a closure around the method and capturing it's arguments as well
|
51
|
+
## This is so it can be replayed. Notice again, I cache the method with a define_method
|
52
|
+
##
|
53
|
+
def method_missing(method_name, *arguments)
|
54
|
+
proc=lambda do |*args|
|
55
|
+
send=lambda {|each| each.send(method_name, *args)}
|
56
|
+
@sends << send
|
57
|
+
self
|
58
|
+
end
|
59
|
+
self._class.send(:define_method, method_name, &proc)
|
60
|
+
proc.call(*arguments)
|
61
|
+
end
|
62
|
+
|
63
|
+
def respond_to?(symbol,include_private = false)
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
## Do a placebo collect to get it to create an array with the elements
|
69
|
+
##
|
70
|
+
def to_real
|
71
|
+
collect(&PLACEBO)
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
## Call each member in the original collection and call each "captured" method
|
76
|
+
## in succession. Notice the use of inject to make this really elegant and succint.
|
77
|
+
## I do cheat a little and realize the collection and then call each. I want
|
78
|
+
## to change this in the future. Actually, 1.9 will make this possible. We'll
|
79
|
+
## be able to use iterators and will make below more lazy.
|
80
|
+
##
|
81
|
+
def each(&block)
|
82
|
+
answer = @internal.call do |each|
|
83
|
+
@sends.inject(each) do |result, each_send |
|
84
|
+
each_send.call(result)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
answer.each(&block)
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
## Give me the size. This can be dangerous if you ever wrap an infinite enumerable
|
92
|
+
##
|
93
|
+
def size
|
94
|
+
inject(0) {|sum,each| sum + 1 }
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_lazy
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
79
103
|
end
|
data/lib/lazy_enumerable.rb
CHANGED
@@ -1,7 +1,2 @@
|
|
1
1
|
require 'lazy/extensions'
|
2
|
-
require 'lazy/
|
3
|
-
require 'lazy/lazy_enumerable'
|
4
|
-
require 'lazy/collect_enumerable'
|
5
|
-
require 'lazy/reject_enumerable'
|
6
|
-
require 'lazy/select_enumerable'
|
7
|
-
require 'lazy/message_collector'
|
2
|
+
require 'lazy/lazy_enumerable'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: LazyEnumerable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blaine Buxton
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-10-
|
12
|
+
date: 2008-10-06 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -26,13 +26,8 @@ files:
|
|
26
26
|
- tests/lazy_enumerable_test.rb
|
27
27
|
- tests/lazy_enumerable_test_suite.rb
|
28
28
|
- lib/lazy
|
29
|
-
- lib/lazy/abstract_enumerable.rb
|
30
|
-
- lib/lazy/collect_enumerable.rb
|
31
29
|
- lib/lazy/extensions.rb
|
32
30
|
- lib/lazy/lazy_enumerable.rb
|
33
|
-
- lib/lazy/message_collector.rb
|
34
|
-
- lib/lazy/reject_enumerable.rb
|
35
|
-
- lib/lazy/select_enumerable.rb
|
36
31
|
- lib/lazy_enumerable.rb
|
37
32
|
- README
|
38
33
|
- LICENSE
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Lazy
|
2
|
-
class AbstractEnumerable
|
3
|
-
PLACEBO=lambda {|each| each}
|
4
|
-
|
5
|
-
##
|
6
|
-
## Remove any unnecessary methods so that method_missing is invoked
|
7
|
-
##
|
8
|
-
def self.wack_all_my_methods
|
9
|
-
to_wack = instance_methods.reject do |each|
|
10
|
-
['===','method_missing'].include?(each) || each =~ /^__/
|
11
|
-
end
|
12
|
-
to_wack.each do |each|
|
13
|
-
alias_method("_#{each}", each)
|
14
|
-
undef_method(each)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.iterator_creator(*method_names)
|
19
|
-
method_names.each { |every| iterator_creator_for(every) }
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.iterator_creator_for(method_name)
|
23
|
-
non_lazy_name = /lazy_(.+)/.match(method_name.to_s)[1].to_sym
|
24
|
-
define_method(method_name) { iterator_class.new(_method(non_lazy_name)) }
|
25
|
-
end
|
26
|
-
|
27
|
-
wack_all_my_methods
|
28
|
-
include Enumerable
|
29
|
-
iterator_creator :lazy_select, :lazy_collect, :lazy_reject, :lazy_detect, :lazy_each
|
30
|
-
|
31
|
-
##
|
32
|
-
## Give me the size. This can be dangerous if you ever wrap an infinite enumerable
|
33
|
-
##
|
34
|
-
def size
|
35
|
-
inject(0) {|sum,each| sum + 1 }
|
36
|
-
end
|
37
|
-
|
38
|
-
def to_lazy
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
##
|
43
|
-
## This should be added with definition of the iterator class
|
44
|
-
##
|
45
|
-
def iterator_class
|
46
|
-
raise(NotImplementedError, "iterator_class", caller);
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
###
|
2
|
-
### LazyEnumerable makes the implementation of higher order methods easier. LazyIterator
|
3
|
-
### is a simple implemetation of that. It basically works by "stacking" up the method
|
4
|
-
### calls until the collection needs to be calculated (realized). It then calls the
|
5
|
-
### "stacked up" methods.
|
6
|
-
###
|
7
|
-
### LazyEnumerable is immutable and I would like LazyIterator to be as well. But,
|
8
|
-
### every attempt has made the code ugly and inelegant. I'm still looking for a good
|
9
|
-
### solution. Immuntability gives the ability to calculate on different levels.
|
10
|
-
###
|
11
|
-
module Lazy
|
12
|
-
|
13
|
-
class MessageCollector < AbstractEnumerable
|
14
|
-
|
15
|
-
def initialize(proc)
|
16
|
-
@internal=proc
|
17
|
-
@sends=[]
|
18
|
-
end
|
19
|
-
|
20
|
-
##
|
21
|
-
## Simply make a closure around the method and capturing it's arguments as well
|
22
|
-
## This is so it can be replayed. Notice again, I cache the method with a define_method
|
23
|
-
##
|
24
|
-
def method_missing(method_name, *arguments)
|
25
|
-
proc=lambda do |*args|
|
26
|
-
send=lambda {|each| each.send(method_name, *args)}
|
27
|
-
@sends << send
|
28
|
-
self
|
29
|
-
end
|
30
|
-
self._class.send(:define_method, method_name, &proc)
|
31
|
-
proc.call(*arguments)
|
32
|
-
end
|
33
|
-
|
34
|
-
def respond_to?(symbol,include_private = false)
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
##
|
39
|
-
## Do a placebo collect to get it to create an array with the elements
|
40
|
-
##
|
41
|
-
def to_real
|
42
|
-
collect(&PLACEBO)
|
43
|
-
end
|
44
|
-
|
45
|
-
##
|
46
|
-
## Call each member in the original collection and call each "captured" method
|
47
|
-
## in succession. Notice the use of inject to make this really elegant and succint.
|
48
|
-
## I do cheat a little and realize the collection and then call each. I want
|
49
|
-
## to change this in the future.
|
50
|
-
##
|
51
|
-
def each(&block)
|
52
|
-
answer = @internal.call do |each|
|
53
|
-
@sends.inject(each) do |result, each_send |
|
54
|
-
each_send.call(result)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
answer.each(&block)
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
class AbstractEnumerable
|
63
|
-
def iterator_class
|
64
|
-
MessageCollector
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|