What are the Ruby Gotchas a newbie should be warned about?
ruby
Solution
Wikipedia Ruby gotchas
From the article:
- Names which begin with a capital letter are treated as constants, so local variables should begin with a lowercase letter.
- The characters `$` and `@` do not indicate variable data type as in Perl, but rather function as scope resolution operators.
- To denote floating point numbers, one must follow with a zero digit (`99.0`) or an explicit conversion (`99.to_f`). It is insufficient to append a dot (`99.`), because numbers are susceptible to method syntax.
- Boolean evaluation of non-boolean data is strict: `0`, `""` and `[]` are all evaluated to `true`. In C, the expression `0 ? 1 : 0` evaluates to `0` (i.e. false). In Ruby, however, it yields `1`, as all numbers evaluate to `true`; only `nil` and `false` evaluate to `false`. 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, but `nil` on failure (e.g., mismatch). This convention is also used in Smalltalk, where only the special objects `true` and `false` can be used in a boolean expression.
- Versions prior to 1.9 lack a character data type (compare to C, which provides type `char` for characters). This may cause surprises when slicing strings: `"abc"[0]` yields `97` (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 already `true`. This is because `statement until expression` is actually syntactic sugar over
until expression
statement
end
, the equivalent of which in C/C++ is `while (not(expression)) statement;` just like `statement if expression` is an equivalent to
if expression
statement
end
However, the notation
begin
statement
end until expression
in Ruby will in fact run the statement once even if the expression is already true.
- Because constants are references to objects, changing what a constant refers to generates a warning, but modifying the object itself does not. For example, `Greeting << " world!" if Greeting == "Hello"` does not generate an error or warning. This is similar to `final` variables 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, `and` and `or`, do not follow the normal rules of precedence: `and` does not bind tighter than `or`. Ruby also has expression operators `||` and `&&` which work as expected.
`def` inside `def` doesn't do what a Python programmer might expect:
def a_method
x = 7
def print_x; puts x end
print_x
end
This gives an error about `x` not being defined. You need to use a `Proc`.
Language features
- Omission of parentheses around method arguments may lead to unexpected results if the methods take multiple parameters. The Ruby developers have stated that omission of parentheses on multi-parameter methods may be disallowed in future Ruby versions; the current (November 2007) Ruby interpreter throws a warning which encourages the writer not to omit `()`, 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 called `method_missing()`.
Problem
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?