Search code examples
rubymethodsenumerable

Trying to write my own all? method in Ruby


There is a method called all? in Enumerable.

I'm trying to learn all the methods of Enumberable's library by writing them myself.

This is what I've come up so far for the all? method. I sorta understand it but I got stumped when trying to pass initialized values to my method.

EDIT for the record, I'm aware that enum method that I have is not the right way ie, it's hard-coded array. This is for self-learning purposes. I'm just trying to figure out how to pass the initialized values to my all? method. That's why I wrote enum in the first place, to see that it is working for sure. Please don't take this class as a literal gospel. Thank you.

class LearningMethods

  def initialize(values)
    @values = values
  end

  def enum
    array = [10, 3, 5]
  end


  def all?(a)
    yield(a)
  end

end

c = LearningMethods.new([10, 3, 5])
p c.enum.all? {|x| x >= 3 } #this works

p c.all?(10) { |x| x >= 3 } #this works

p c.all?(@values) { |x| x >= 3 } #this doesn't work. Why not? And how do I pass the initialized values? 

Solution

  • I'm not sure why you need enum at all? Enumerable is a module included in array, so if you're not familiar with this I recommend you read about "modules and mix-ins" in Ruby.

    all? works simply by passing EACH of the array elements to the block. If there is ANY element (at least 1) for which the block returns false, then all? evaluates to false. Try analyzing this code:

    class MyAllImplementation
      def initialize(array)
        @array = array
      end
    
      def my_all?
        @array.each do |element| # for each element of the array
          return true unless block_given? # this makes sure our program doesn't crash if we don't give my_all? a block.
          true_false = yield(element) # pass that element to the block
          return false unless true_false # if for ANY element the block evaluates to false, return false
        end
        return true # Hooray! The loop which went over each element of our array ended, and none evaluted to false, that means all elements must have been true for the block.
      end
    end
    
    
    a = MyAllImplementation.new([1,2,3])
    p a.my_all? { |x| x > 0 } #=> true
    p a.my_all? { |x| x > 1 } # false, because 1 is not bigger than 1, it's equal to 1