1

Sometimes, you want to use an if/unless modifier but the conditionally executed part includes a local variable that is to be defined within the condition. For example,

a = [1, 2, 3]
n = 3*(x**2) + 4*x + 5 if x = a[2]
m = 6*(y**2) + 7*y + 8 unless (y = a[0]).zero?

will give a parsing error because x,y is read before the if/unless modifier. In order to avoid that, I think it is pretty much common (at least for me) to use and instead of if and or instead of unless:

x = a[2] and n = 3*(x**2) + 4*x + 5
(y = a[0]).zero? or m = 6*(y**2) + 7*y + 8

Besides the fact that it does not raise an error, is there any difference? Is there any side effects in doing this? And, is there a better way?

sawa
  • 165,429
  • 45
  • 277
  • 381
  • 1
    What you're really talking about is common coding style for a particular language. In Perl it's very common to do assignments in `if` tests and short boolean tests followed by `and` or `or` joining in some operation. That might be part of why Perl programs often look like line noise too. :-) In Ruby we tend to not do that since there's not a lot gained by the terseness, and it isn't as obvious/clear what is meant which can lead to maintenance problems. I've seen recommendations that Perl developers stop writing that way but some think it's macho and others are fighting old habits. – the Tin Man Apr 05 '11 at 19:44
  • 1
    Related to, but the opposite of http://stackoverflow.com/questions/2291646/in-ruby-why-wont-foo-true-unless-definedfoo-make-the-assignment – Andrew Grimm Apr 06 '11 at 00:00

3 Answers3

2

Alternatives that I would choose (and have used) when this issue arises:

if x=a[2]
  n = 3*(x**2) + 4*x + 5
end

if x=a[2] then n = 3*(x**2) + 4*x + 5 end

x=nil
n = 3*(x**2) + 4*x + 5 if x=a[2]
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • I realized that your second option might not be so bad. – sawa Apr 05 '11 at 16:55
  • The first two have the added value of placing the variable assignment first, where it will be read before the statement that uses it. I most commonly encounter the first. I do not like the third. – Rein Henrichs Apr 05 '11 at 17:21
0

the logical or returns true if one of the sides evaluates to true...

are you sure that the or and unless lines are equal (could be, that the or line always evaluates to true since m = 6*(y**2) + 7*y + 8 is true)?

EDIT:

nope i was wrong take a look at this doc - seems to be what you are looking for

Stephan
  • 1,639
  • 3
  • 15
  • 26
0

I just realized that there is a difference between

if x = something then f(x) end          (1)

and

x = something and f(x)                  (2)

That is when something takes the value false. In this case, (1) returns nil, whereas (2) returns false.

sawa
  • 165,429
  • 45
  • 277
  • 381