Class: Lazy::LazyEnumerable
- Inherits:
-
Object
- Object
- Lazy::LazyEnumerable
- Includes:
- Enumerable
- Defined in:
- lib/lazy/lazy_enumerable.rb
Constant Summary collapse
- PLACEBO =
lambda {|each| each}
Class Method Summary collapse
- .iterator_creator(*method_names) ⇒ Object
- .iterator_creator_for(method_name) ⇒ Object
-
.wack_all_my_methods ⇒ Object
Remove any unnecessary methods so that method_missing is invoked.
Instance Method Summary collapse
-
#each(&block) ⇒ Object
Call each member in the original collection and call each “captured” method in succession.
-
#initialize(proc) ⇒ LazyEnumerable
constructor
A new instance of LazyEnumerable.
-
#method_missing(method_name, *arguments) ⇒ Object
Simply make a closure around the method and capturing it’s arguments as well This is so it can be replayed.
- #respond_to?(symbol, include_private = false) ⇒ Boolean
-
#size ⇒ Object
Give me the size.
- #to_lazy ⇒ Object
-
#to_real ⇒ Object
Do a placebo collect to get it to create an array with the elements.
Constructor Details
#initialize(proc) ⇒ LazyEnumerable
Returns a new instance of LazyEnumerable.
44 45 46 47 |
# File 'lib/lazy/lazy_enumerable.rb', line 44 def initialize(proc) @internal=proc @sends=[] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *arguments) ⇒ Object
Simply make a closure around the method and capturing it’s arguments as well This is so it can be replayed. Notice again, I cache the method with a define_method
53 54 55 56 57 58 59 60 61 |
# File 'lib/lazy/lazy_enumerable.rb', line 53 def method_missing(method_name, *arguments) proc=lambda do |*args| send=lambda {|each| each.send(method_name, *args)} @sends << send self end self._class.send(:define_method, method_name, &proc) proc.call(*arguments) end |
Class Method Details
.iterator_creator(*method_names) ⇒ Object
29 30 31 |
# File 'lib/lazy/lazy_enumerable.rb', line 29 def self.iterator_creator(*method_names) method_names.each { |every| iterator_creator_for(every) } end |
.iterator_creator_for(method_name) ⇒ Object
33 34 35 36 |
# File 'lib/lazy/lazy_enumerable.rb', line 33 def self.iterator_creator_for(method_name) non_lazy_name = /lazy_(.+)/.match(method_name.to_s)[1].to_sym define_method(method_name) { LazyEnumerable.new(_method(non_lazy_name)) } end |
.wack_all_my_methods ⇒ Object
Remove any unnecessary methods so that method_missing is invoked
19 20 21 22 23 24 25 26 27 |
# File 'lib/lazy/lazy_enumerable.rb', line 19 def self.wack_all_my_methods to_wack = instance_methods.reject do |each| ['===','method_missing'].include?(each) || each =~ /^__/ end to_wack.each do |each| alias_method("_#{each}", each) undef_method(each) end end |
Instance Method Details
#each(&block) ⇒ Object
Call each member in the original collection and call each “captured” method in succession. Notice the use of inject to make this really elegant and succint. I do cheat a little and realize the collection and then call each. I want to change this in the future. Actually, 1.9 will make this possible. We’ll be able to use iterators and will make below more lazy.
81 82 83 84 85 86 87 88 |
# File 'lib/lazy/lazy_enumerable.rb', line 81 def each(&block) answer = @internal.call do |each| @sends.inject(each) do |result, each_send | each_send.call(result) end end answer.each(&block) end |
#respond_to?(symbol, include_private = false) ⇒ Boolean
63 64 65 |
# File 'lib/lazy/lazy_enumerable.rb', line 63 def respond_to?(symbol,include_private = false) true end |
#size ⇒ Object
Give me the size. This can be dangerous if you ever wrap an infinite enumerable
93 94 95 |
# File 'lib/lazy/lazy_enumerable.rb', line 93 def size inject(0) {|sum,each| sum + 1 } end |
#to_lazy ⇒ Object
97 98 99 |
# File 'lib/lazy/lazy_enumerable.rb', line 97 def to_lazy self end |
#to_real ⇒ Object
Do a placebo collect to get it to create an array with the elements
70 71 72 |
# File 'lib/lazy/lazy_enumerable.rb', line 70 def to_real collect(&PLACEBO) end |