3 ms·
Maybe it's because I learned Ruby after Perl and Python (and C and C++ for that matter), but I find it too quirky. e.g. These three expressions have three diff
by emmelaich 8y ago
Maybe it's because I learned Ruby after Perl and Python (and C and C++ for that matter), but I find it too quirky.
e.g. These three expressions have three different values:
1 + 2
+ 3 + 4
(1 + 2
+ 3 + 4)
1 + 2 +
3 + 4
3, 7 and 10 respectively. Because newline is equivalent to semicolon and Ruby allows void expressions.
I just tested Crystal and it does the same.
- vidarh 8y agoNewline is not equivalent to semicolon (or your last example would fail), but Ruby treats a newline as terminating an expression if in a production in the grammar where terminating the expression is valid. In terms of "void", Ruby has no such thing - every expression has a value, though that value can be nil (and somewhat confusingly "( )" is an expression that evaluates to nil). So your first example is two expressions, and evaluates to 7 when the whole thing is evaluated, not 3 - if you evaluate it in irb etc. you might see 3 because the first expressions is itself complete, and so will cause output. Your second example is a list of the expressions "1 + 2" and "3+4", which evaluates to 7, because as for the first example, the last expression evaluated is what will be returned outside of a read-eval loop like in irb. The last example is a single expression because "1 + 2 +" is a syntax error on its own. I can understand you find it quirky, but you generally only need to consider that if you want to break up an expression you need to ensure it does not stand on its own.
- emmelaich 8y agoOK, newline is not equivalent to semicolon but I could be forgiven for inferring that from the documentation. e.g. "an expression is terminated with a newline or semicolon" (https://www.cs.auckland.ac.nz/references/ruby/doc_bundle/Manual/man-1.4/syntax.html#program https://www.cs.auckland.ac.nz/references/ruby/doc_bundle/Man...) Re "void" I'm referring to rubocop warnings like "Operator + used in void context." Here's another oddity; irb behaves differently for some expressions. not_defined = "#{not_defined}" => "" :-/ Anyway, the parens things bothers me the most. In most (all?) other languages, putting parens around a multiline expression would make it one atomic expression.
- vidarh 8y agoYeah, I understands it's confusing. The Ruby grammar does have some dark corners like that where the side effect of trying to make it possible to make things as free of punctuation as possible causes weirdness elsewhere. Putting parens around it does make it one atomic expression though, it's just that in effect the "operators" are ;/lf, and these "pseudo-operators" return the value of the last sub-expression, and binds tighter than parens, I can't actually remember seeing any one relying on grouping expressions with (), though, which is probably just as well. (I'm sure someone will now come up with an "essential" use of it)