6 ms·
I can't stress enough how important it is to _not_ use `and` and `or`. As a former die-hard fan of those operators, it bit me in the ass so hard when those didn
by kreeger 14y ago
I can't stress enough how important it is to _not_ use `and` and `or`. As a former die-hard fan of those operators, it bit me in the ass so hard when those didn't exactly work the way they were supposed to. I've been using && and || now for years and I haven't looked back. /PSA
- alanctgardner2 14y agoTo anyone who's wondering, it seems like 'and' and 'or' are the same as && and ||, but with lower precedence [0]. Does anyone have a good reason why they both exist? It's a pretty big gotcha. [0] http://stackoverflow.com/questions/1426826/difference-between-and-and-in-ruby http://stackoverflow.com/questions/1426826/difference-betwee...
- philwelch 14y agoIt's an imported Perlism, back from the days of the old assert idiom `foo == bar or die`. If `foo == bar` evaluates to true, the `or` is short-circuited, else it calls the built-in `die` function which kills the process.
- lloeki 14y agoMore precisely && and || are meant to stand in boolean tests, whereas and and or are meant to tie expressions together DSL style, as an alternative to if/then, like so: @current_user.logged_in? or redirect_to login_path @current_user.can? :do_this or render :status => 403 shirt.blue? and return bar put_suit_on or put_pants_on
- graywh 14y agoThat's a good example shirt.blue? and return bar would be equivalent to return bar if shirt.blue? You can do the same with or and unless.
- philwelch 14y agoI find the postfix if and unless far more readable than the Perlish and and or operators. The "or die" construction for asserts is really amusing though.
- gurkendoktor 14y ago&&/|| can bite you just as well: if first_user = User.find(4) && second_user = User.find(6) ... end
- rauljara 14y agoI may be missing something obvious here. How would this code bite you?
- alanctgardner2 14y ago> first_user = User.find(4) && second_user = User.find(6) It looks like it would evaluate as: first_user = (User.find(4) and second_user = User.find(6)) That is to say, the assignment comes after the boolean operation, which is unexpected.
- pooriaazimi 14y agoWell, I expect first_user = User.find(4) && second_user = User.find(6) to be literally equivalent to second_user = User.find(6) first_user = User.find(4) && second_user I honestly can't see why you might want it to mean something else... Edit: I see. if you do something like if (first_user = User.find(4) && second_user = User.find(6)) { .. } it might bite you. You might expect it to be equivalent to first_user = User.find(4) second_user = User.find(6) if (first_user && second_user) { .. } which I personally think is a very, very bad practice. Parenthesis should always be used when there's even the slightest possibility that you or another maintainer/contributor might be confused about.
- alanctgardner2 14y agoPersonally, I'm almost painfully verbose with my parens to avoid exactly this scenario. Better to be explicit about my intent to the interpreter and other coders. Having an assignment that could be skipped by short-circuiting also seems like bad practice, but I realize it was designed to be a toy example
- look_lookatme 14y agoAgreed. It's just not worth it, especially with implicit return.
- sabat 14y agoThey're not synonyms; "and" is not a more readable version of "&&". As Avdi Grimm says: and and or, despite an apparent similarity to && and ||, have very different roles. It's worth using "and" and "or", especially considering that && and || bind too tightly for some purposes. I try to avoid && and || unless I'm doing a specific boolean operation (e.g. x = foo || bar). Not for flow control, though. If you really can't grok the logic, use parens.
- Pewpewarrows 14y agoI agree. But in all code that I write, regardless of pretty much whatever language it's written in, I always explicitly add parentheses around what I want the order of operations to be. "1 * 3 + 4 / 20 && foo" is unreadable. No one wants to memorize the order of operations for every language they use and have to figure it out in their head. Make life easier for the people who have to maintain that line of code you just wrote.
- prawks 14y agoI can't believe more people don't do this. It seems like such a no-brainer when I'm writing. Not only for others, but for myself as well.
- oinksoft 14y agoFor language-specific operators I could understand ... but to me, the cognitive load of the parentheses is worse than having to think for a moment about this particular set of operators which have the same precedence in every language I've used (and the arithmetic operators which I've had to know the order of since early grade school). Maybe I'll eat my foot some day, but (a == 1) && (b == 2) or (2 * 3) + 1 is nothing but code smell to me.
- sirclueless 14y agoThose are both perfectly reasonable to me. There are in fact languages that would interpret your example #1 incorrectly, so if someone wants to disambiguate I have no qualms. Your example #2 is sort of braindead, but in a more complicated expression, where 2 3 or 1 were method calls or something, I would appreciate the parens.
- Pewpewarrows 14y agoThere are plenty of things that you can leave out when writing parseable source code, but don't because it would make the code horribly un-readable. That is, there's a reason for whitespace around operators, after commas, extraneous newlines, etc. It makes the code easier to read and maintain. Now while I'm willing to admit that this whole area is largely aesthetic and personal, if you submitted a line of code to me that was just this without the parentheses: > 2 * 3 + 1 I would reject the code review in a heartbeat. Part of making your code readable to others and less error-prone during maintenance is adding extraneous stuff to it that isn't necessary for the code to parse/compile/interpret.
- graywh 14y agoAvdi Grimm gives a good explanation: http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/ http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/