43

I have a method and in order to check whether it is being passed a block, I do the following:

if block_given?
    res = yield(array[i], array[i+1])
  else
    res = array[i] - array[i+1]
  end

However RuboCop is giving me a warning which I don't really understand in the if block_given? line:

Use the return of the conditional for variable assignment and comparison

Is there any other more rubyist way of doing this?

Thanks

noloman
  • 11,411
  • 20
  • 82
  • 129

1 Answers1

76

What the warning is telling you to do is:

res = if block_given?
        yield(array[i], array[i+1])
      else
        array[i] - array[i+1]
      end

That is, having a single assignment instead of two (or even more).

Ilya
  • 13,337
  • 5
  • 37
  • 53
JFMR
  • 23,265
  • 4
  • 52
  • 76
  • 4
    maybe `res = block_given? ? yield(array[i], array[i + 1]) : array[i] - array[i + 1]` would be valid too? – noloman Feb 11 '18 at 11:39
  • 1
    Sure, but this one seems to be more readable. Specially if there are multiple branches (think of nesting `? :`). – JFMR Feb 11 '18 at 11:40
  • 1
    also, alignment is important for Rubocop. – Ilya Feb 11 '18 at 11:46
  • 3
    noloman, yes, and I think that’s preferable. The [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) favours the use of ternery expressions, provided (as here) there is only one expression per branch and those expressions are not themselves terneries. I agree. – Cary Swoveland Feb 11 '18 at 15:54
  • just watch out to Rubocop indentation rules. Depending on your setup, else and end must be aligned to `res` and not to `if` – fagiani Jul 21 '18 at 21:57