Search code examples
rubyrubocop

Use guard for ruby convert raise exception if else


Rubocop keeps throwing me the error: Use a guard clause (raise "no block" if not block_given?) instead of wrapping the code inside a conditional expression.

# frozen_string_literal: true

def bubble_sort_by(arr)
    if block_given?
        swap = -1
        while swap != 0
            swap = 0
            (0..(arr.length - 2)).each do |i|
                if yield(arr[i], arr[i + 1]).positive?
                    arr[i], arr[i + 1] = arr[i + 1], arr[i]
                    swap += 1
                end
            end
        end
    else
        raise "no block"
    end
    arr
end

#given test
bubble_sort_by(["hey", "hello", "hi"]) {|left, right| left.length - right.length
}

Tried with unless but still the same, and I don't understand how should I convert to guard clause.


Solution

  • If you have if-else wrapping the whole method body and else only wraps raising an error, you can refactor to:

    def bubble_sort_by(arr)
      raise "no block" unless block_given?
      swap = -1
      while swap != 0
        swap = 0
        (0..(arr.length - 2)).each do |i|
          if yield(arr[i], arr[i + 1]).positive?
            arr[i], arr[i + 1] = arr[i + 1], arr[i]
            swap += 1
          end
        end
      end
      arr
    end
    

    You have a condition on the top, and the main part of the method is after it.