Project

General

Profile

Bug #15768

"and", &&, boolean issue, different ruby versions, confusing

Added by daBee (da Bee) 7 months ago. Updated 7 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin15]
[ruby-core:92290]

Description

Just caught this:

# version 2.5.1, Mac OS

v1 = true and false                                # => IRB: true
p v1                                            # => app.rb: true, IRB: false
v2 = true && false                                 # => IRB: false
p v2                                           # => app.rb: false, IRB: false
puts 1 > -1 && 257 < 256            # => app.rb: false, IRB: false

IRB Mac OS 2.6.2

>> v1 = true and false
=> false
>> v2 = true && false
=> false
>> puts v1
true
=> nil
>> puts v2
false
=> nil

I might be missing something, but I think there's an issue here, on both versions 2.5.1 and 2.6.2.

Associated revisions

Revision 54eac83b
Added by nobu (Nobuyoshi Nakada) 7 months ago

Hide internal IDs

  • parse.y (internal_id): number the ID serial for internal use by counting down from the neary maximum value, not to accidentally match permanent IDs.

[Bug #15768]

Revision 41d6bc37
Added by nagachika (Tomoyuki Chikanaga) 4 months ago

merge revision(s) d0ba4abf1a00339ebbb5d405db3240a8bdb7b68b,54eac83b2ad77ddea84fa6d66c09e0bb014cf61e: [Backport #15786]

    Add RB_ID_SERIAL_MAX


    Hide internal IDs

    * parse.y (internal_id): number the ID serial for internal use by
      counting down from the neary maximum value, not to accidentally
      match permanent IDs.

    [Bug #15768]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67718 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 401da791
Added by usa (Usaku NAKAMURA) 3 months ago

merge revision(s) d0ba4abf1a00339ebbb5d405db3240a8bdb7b68b,54eac83b2ad77ddea84fa6d66c09e0bb014cf61e: [Backport #15786]

    Add RB_ID_SERIAL_MAX


    Hide internal IDs

    * parse.y (internal_id): number the ID serial for internal use by
      counting down from the neary maximum value, not to accidentally
      match permanent IDs.

    [Bug #15768]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 67758
Added by usa (Usaku NAKAMURA) 3 months ago

merge revision(s) d0ba4abf1a00339ebbb5d405db3240a8bdb7b68b,54eac83b2ad77ddea84fa6d66c09e0bb014cf61e: [Backport #15786]

Add RB_ID_SERIAL_MAX


Hide internal IDs

* parse.y (internal_id): number the ID serial for internal use by
  counting down from the neary maximum value, not to accidentally
  match permanent IDs.

[Bug #15768]

History

Updated by Hanmac (Hans Mackowiak) 7 months ago

does it have something to do with different precendence?

https://ruby-doc.org/core-2.6.2/doc/syntax/precedence_rdoc.html

Updated by chrisseaton (Chris Seaton) 7 months ago

I think there's two things confusing you here.

Firstly, v1 = true and false is ((v1 = true) and false), while v2 = true && false is (v2 = (true && false)). --dump=parser will tell you this.

Secondly, when you do v1 = true and false in IRB and it prints the result you are really doing p (v1 = true and false), not v1 = true and false; p v1 which is what I think you're imagining.

I think those two things explain all the differences you're seeing, and my understanding is all that behaviour is as per design, documentation, and specs.

I do see why it could be confusing though.

Updated by zverok (Victor Shepelev) 7 months ago

It is a conscient (though controversial according to some) design decision, borrowed from Perl.

&& and and are NOT synonyms. &&/|| are boolean operators, while and/or are control-flow operators.
Demonstrated behavior is useful in statements ending with (and|or) (exit|return|raise):

foo = some_value || other_value && third_value or raise "No branch have produced really good value"

this && that || something and return "All branches produced some undesirable result"

That's why those operators have the lowest possible precedence -- to be performed definitely AFTER the rest of the statement.

I really like this feature, but should also say that confusion about && vs and is so high, that they are banned explicitly by Bozhidar Batsov's "Ruby Style Guide" (for context: very heated discussion), and even half of the standard library uses and and or in boolean context.

Updated by shevegen (Robert A. Heiler) 7 months ago

&& and and are NOT synonyms.

The old pickaxe made that clear too, like in 2004 already or so.

Perhaps the official documentation could mention this more clearly. Admittedly
I knew about this primarily (and initially) because I read the pickaxe back in
the days.

foo = some_value || other_value && third_value or raise "No branch have
produced really good value"

That's why those operators have the lowest possible precedence -- to be
performed definitely AFTER the rest of the statement.

I am not entirely sure that this would have the be the main (or only) use
case, but it was of course a deliberate decision. Changing this would not
have a massive net benefit in my opinion, well aside from backwards
incompatibility issues.

Personally I dislike complicated decision chains such as the above. My brain needs
to understand what is going on and it always takes me needlessly long to "decode"
what the intent is. I understand that people want to be concise and super short in
the code that they write, which is fine, but the world is not going to run out of
\n newlines any time soon. Then again, the style of different ruby users can be vastly
different and it is quite natural to prefer one style over another.

I really like this feature, but should also say that confusion about && vs
and is so high, that they are banned explicitly by Bozhidar Batsov's "Ruby
Style Guide" (for context: very heated discussion), and even half of the
standard library uses and and or in boolean context.

Well, let's for the moment ignore confusion and style guide - I think the
only practical approach about this is to provide people with sufficient
information via the main entry site (for the ruby documentation). Because
the ruby documentation, while it is ok, is still not really great. One
reason why the pickaxe was so useful, at the least to me back in the days,
was primarily because it put a lot of information into one place, and it
was easy to read, and quite detailed. The official documentation on the
other hand was ... hmm. A bit more boring to read, and not quite on the
same level of quality, IMO.

Of course the official documentation also has other goals, such as being a "fast
reference", so it won't explain a lot about style issues, or how to write code;
but still, some things, such as the "&&" versus "and", could probably also be
explained better on the main documentation.

Personally my two main style guides are the subjective quality analysis
by my brain :) and what the ruby parser allows. I don't use other style
guides per se, although rubocop has several other benefits in my opinion
such as auto-correct. But to refer specifically to "and" versus "&&" -
while I do not agree that any "guide" should "ban" anything, ever, when
the ruby parser instead accepts it, I think that in many ways "and" is
easier to read. People are of course very used to &&, but in my opinion
"and" often leads to nicer-to-read code. I have not made any statistical
analysis in my own code, but I can tell you off the top of my head that
I vastly use "and", as opposed to "&&". I don't have any clear policy of
banning or not banning, but just my "natural" flow of writing ruby code
clearly favours "and". (That also means that I may have to use () more
often but I am fine with that.)

What may be interesting, though well aside from this issue, may be to
perform some statistical analysis in general, as to what different ruby
users may use, e. g. in their own code base (or at the least the gems
published on rubygems.org). Although I have no data to prove anything,
my intuition says that "and" is used a lot more often in ruby code
these days. But I could be wrong, too - really just guessing/guestimating
here.

even half of the standard library uses and and or in boolean context.

Well, we need to remember that different people contributed code, and
very old ruby code often looks quite different from "modern" ruby code
aka written in the last ~3 years.

By the way, last but not least - the old pickaxe also mentioned that irb
behaves a bit differently from the main ruby parser. I guess daBee did not
read the pickaxe, which may also be a question of time (people today are
probably less likely to read the pickaxe, as compared to e. g. the year
2006 or so). The best approach, IMO, would be to improve on the documentation
whenever people don't seem to find what they wanted to know or tried to
figure out / understand.

Updated by duerst (Martin Dürst) 7 months ago

  • Status changed from Open to Closed

This is per spec as explained, so I'm closing it.

If you should want to change it, please create a feature request, and explain in detail what the change would do and how it would be backwards compatible.

Also available in: Atom PDF