0

what is the best way to check condition and run method in Ruby? which one is most readable?

bar if foo

or

foo and bar

ajahongir
  • 469
  • 5
  • 11

2 Answers2

2

I would use one over the other depending on the situation.

If I am interested in running a method depending on a condition met (aka condition does not have a side effect):

do_something if this_condition_is_true

If I am interested in running a method only if another method finished successfully (aka both methods have side effects):

do_something and do_something_other
sawa
  • 165,429
  • 45
  • 277
  • 381
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • 1
    The latter use-case is a nice consideration. Still, I recommend using `&&` instead of `and`. `and` has a lower priority than assignment. – John Dvorak Aug 14 '14 at 09:49
  • I follow the convention: Use `&&` for conditions (`foo? && bar?`), but use `and` for control flow (`do_this and do_that`). – spickermann Aug 14 '14 at 09:52
  • Way to go. But I'd say the most important part here is "depends on situation" :-) – John Dvorak Aug 14 '14 at 09:54
2

Edit As pointed out by Smar, the following may not be true for the newest Ruby versions. Checking right now. The issue continues here


spickermann provides a good answer, but its second case is not clear enough, so I will spell it out a more.

Usually, you should use if as it is designed for that purpose.

bar if foo

But often, you want to define a local variable on the way of evaluating a condition. In that case, you cannot use the postfix if notation; the following will raise an error (provided that x is not defined prior):

bar(x) if x = h[:foo]

and you have to use and if you want to put it on a single line.

x = h[:foo] and bar(x)
Community
  • 1
  • 1
sawa
  • 165,429
  • 45
  • 277
  • 381
  • 1
    The if is not raising an error for me though; I just threw `h = {} ; bar(x) if x = h[:foo]` to irb. – Smar Aug 14 '14 at 11:04
  • @Smar I just confirmed that too. Something strange is happening. Even the undefined `bar` does not raise an error. – sawa Aug 14 '14 at 11:06
  • I guess it’s new feature of Ruby 2.1 or so. Anyway, undefined `bar()` won’t give an error until it’s evaluated; try this one instead: `h = { :foo => "nyaaan" } ; bar(x) if x = h[:foo]`. If you have `bar` defined, it will be executed, and `x` will be given value. – Smar Aug 14 '14 at 11:07
  • @Smar I see. I didn't know that feature. Then that should be for the same reason. Do you have any reference mentioning that change? – sawa Aug 14 '14 at 11:08
  • No idea, I just tested it now as I saw your answer. I know no real information about this. – Smar Aug 14 '14 at 11:10
  • @Smar I've tested it on Ruby 1.9.3 and: 1st doesn't rise an error, 2nd raise it. – Darek Nędza Aug 14 '14 at 11:29
  • @DarekNędza: but it raises ”undefined method” error, right? Try defining `bar() `and there should be no errors :) – Smar Aug 14 '14 at 11:31
  • @Smar yes, 2nd raise that error but my point was that it's not a new feature as it's works the same in 1.9.3 and 2.1. – Darek Nędza Aug 14 '14 at 11:35
  • @DarekNędza I had believed that the second one should raise an error irrespective of the version, but Smar and I confirmed that it does not on Ruby 2. And you confirmed that it does on Ruby 1.9. So it looks like something changed. – sawa Aug 14 '14 at 11:37
  • Uhm... Second one doesn’t raise error if you define `bar()`, but does if you don’t, as it tries to evaluate a method that does not exist. That’s atleast what happens to me on `irb` with ruby 2.1.1p76. Anyway, there is no syntax errors, just error about missing method. – Smar Aug 14 '14 at 11:40
  • 1
    @Smar The change seems to have happened between 2.1.1 and 2.1.2. I asked a new question [here](http://stackoverflow.com/questions/25306902/has-the-parsing-rule-for-local-variables-changed-in-ruby-2-1-2). – sawa Aug 14 '14 at 11:53
  • oh, it doesn't work raise error on 2.1. I see. – Darek Nędza Aug 14 '14 at 13:06
  • i really prefer to use `and` when want to return some data. `z = x and y`. `z` will be equal 'x' or `y` its something like `z = x || y`. – ajahongir Aug 15 '14 at 11:51