Ruby Language Structure
This chapter describes the syntax constructs and general structure of Ruby programs.
As a brief overview, it can be said that:
- Ruby program consists of expressions dealing with literals, variables and constants.
- Expressions are:
- assignments;
- control expressions;
- method calls;
- definitions of modules, classes and methods.
- Ruby is an object-oriented language, so the program is structured by defining classes and modules and their methods.
- Ruby has open classes that can be changed any time (even the core ones, like
String). To localize class changes and implement hygienic extensions, one can use refinements.
- Ruby has open classes that can be changed any time (even the core ones, like
- Error reporting and handling is done with exceptions.
Note that many of the language constructs you will see in a typical Ruby program, are in fact, just methods. For example Kernel#raise is used to raise an exception, and Module#private is used to change a method’s visibility. As a result, the language core described in this chapter is pretty small, and everything else just follows usual rules for modules, methods and expressions.
Ending an Expression
Ruby uses a newline as the end of an expression. When ending a line with an operator, open parentheses, comma, etc. the expression will continue.
You can end an expression with a ; (semicolon). Semicolons are most frequently used with ruby -e.
Indentation
Ruby does not require any indentation. Typically, ruby programs are indented two spaces.
If you run ruby with warnings enabled and have an indentation mismatch, you will receive a warning.
defined?
defined? is a keyword that returns a string describing its argument:
p defined?(UNDEFINED_CONSTANT) # prints nil
p defined?(RUBY_VERSION) # prints "constant"
p defined?(1 + 1) # prints "method"
You don’t need to use parenthesis with defined?, but they are recommended due to the low precedence of defined?.
For example, if you wish to check if an instance variable exists and that the instance variable is zero:
defined? @instance_variable && @instance_variable.zero?
This returns "expression", which is not what you want if the instance variable is not defined.
@instance_variable = 1
defined?(@instance_variable) && @instance_variable.zero?
Adding parentheses when checking if the instance variable is defined is a better check. This correctly returns nil when the instance variable is not defined and false when the instance variable is not zero.
Using the specific reflection methods such as instance_variable_defined? for instance variables or const_defined? for constants is less error prone than using defined?.