I have recently learned the Ruby programming language, and all in all it is a good language. But I was quite surprised to see that it was not as simple as I had expected. More precisely, the ‘rule of least-surprise’ did not seem very respected to me (of course this is quite subjective). For example:
x = true and false puts x # displays true!
and the famous:
puts 'zero is true!' if 0 # zero is true!
What are the other ‘Gotchas’ you would warn a Ruby newbie about?
Wikipedia Ruby gotchas
From the article:
$and@do not indicate variable data type as in Perl, but rather function as scope resolution operators.99.0) or an explicit conversion (99.to_f). It is insufficient to append a dot (99.), because numbers are susceptible to method syntax.0,''and[]are all evaluated totrue. In C, the expression0 ? 1 : 0evaluates to0(i.e. false). In Ruby, however, it yields1, as all numbers evaluate totrue; onlynilandfalseevaluate tofalse. A corollary to this rule is that Ruby methods by convention — for example, regular-expression searches — return numbers, strings, lists, or other non-false values on success, butnilon failure (e.g., mismatch). This convention is also used in Smalltalk, where only the special objectstrueandfalsecan be used in a boolean expression.charfor characters). This may cause surprises when slicing strings:'abc'[0]yields97(an integer, representing the ASCII code of the first character in the string); to obtain'a'use'abc'[0,1](a substring of length 1) or'abc'[0].chr.The notation
statement until expression, unlike other languages’ equivalent statements (e.g.do { statement } while (not(expression));in C/C++/…), actually never runs the statement if the expression is alreadytrue. This is becausestatement until expressionis actually syntactic sugar over, the equivalent of which in C/C++ is
while (not(expression)) statement;just likestatement if expressionis an equivalent toHowever, the notation
in Ruby will in fact run the statement once even if the expression is already true.
Greeting << ' world!' if Greeting == 'Hello'does not generate an error or warning. This is similar tofinalvariables in Java, but Ruby does also have the functionality to ‘freeze’ an object, unlike Java.Some features which differ notably from other languages:
The usual operators for conditional expressions,
andandor, do not follow the normal rules of precedence:anddoes not bind tighter thanor. Ruby also has expression operators||and&&which work as expected.definsidedefdoesn’t do what a Python programmer might expect:This gives an error about
xnot being defined. You need to use aProc.Language features
(), to avoid ambiguous meaning of code. Not using()is still common practice, and can be especially nice to use Ruby as a human readable domain-specific programming language itself, along with the method calledmethod_missing().