Reputation: 5940
I want to give all of those ruby treats to my class (working on an underlying data structure). include Enumarable
only does part of the job.
What's the best way?
class A
def initialize
@data = 10.times.map { |e| e }
end
include Enumerable
def each(&block)
@data.each(&block)
end
end
#works great
A.new.each {}
A.new.select {|e| e > 3}
A.new.reject {|e| e > 3}
A.new.partition {|e| e > 3}
A.new.count
# those will fail
A.new.size
A.new.length
A.new.select! {|e| e > 3}
Upvotes: 2
Views: 91
Reputation: 8295
What you provide as an example is no different from an Array
, so you could implement it as follows
class A < Array; end
a = A.new(10.times.map { |e| e })
#works great
a.new.each {}
a.new.select {|e| e > 3}
a.new.reject {|e| e > 3}
a.new.partition {|e| e > 3}
a.new.count
a.new.size
a.new.length
a.new.select! {|e| e > 3}
now of course this has no actual purpose as is, because it is just an Array
, so depending on what else you want this class to do, you could add it as extra functionality.
eg
class A < Array
def contains_the_answer_of_all_things?
include? 42
end
end
so that
a = A.new(10.times.map { |e| e })
a.contains_the_answer_of_all_things?
#=> false
b = A.new(100.times.map {|e| e })
b.contains_the_answer_of_all_things?
#=> true
Upvotes: 1
Reputation: 40333
size
, length
and all the methods that mutate the collection in place, like select!
, are not part of Enumerable
.
If you want them you must implement them yourself.
Upvotes: 3