Hertzel Guinness
Hertzel Guinness

Reputation: 5940

ruby - add Enumerable functionality and more to a class

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

Answers (2)

xlembouras
xlembouras

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

Maur&#237;cio Linhares
Maur&#237;cio Linhares

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

Related Questions