Ruby is quite similar to the other general-purpose programming languages and not so far from the Shell scripts: the interpreter reads the program from the top, evaluates each expression and stores the values in the variables. The script below will print the famous phase "Hello, world.".
puts it is not adding newline at the end.
print "Hello, " puts "world."
More than one expression can be written in one line - in this case you must put the semicolon
; between them. The good practice is to avoid it for readability, but this could be useful in one-liners, like
ruby -e 'print "Hello, "; puts "world."'. The script below is the same as the previous one.
print "Hello, "; puts "world."
Ruby treats end of the line as the end of the expression, except there is an operator (like + or -), colon or backslash at the end of the line. In this case the next line is a continuation of the previous statement. When you define a string using single or double quotes, interpreter treats the newline as a part of the string, until the closing quote.
a = 1 + # the same as 'puts 1 + 3' 2 puts a # prints '3' puts 1, # the same as 'puts 1, 2' 2 # prints '1', newline and '2' puts 1 \ # the same as 'puts 1, 2' ,2 # prints '1', newline and '2' puts 'Hello' \ # the same as "puts 'Hello' 'world.'" ' world.' # prints 'Hello world' puts 'Hello world' # prints 'Hello', newline and 'world'
Everything begins with hash # to the end of the line is treated as a comment and it is not evaluated. There are multi-line comments as well - everything between lines
=end is not evaluated by the interpreter.
# this is a comment =begin this is a comment as well =end
Variables and Constants
The local variable starts with a small letter and may contain letters, digits and underscore
_ sign. The good practice is to use snake case instead of camel case to name the variables, but it is just a convention.
number_one = 1 number_two = 2 sum = number_one + number_two puts sum
The global variable must start with dollar symbol
$, then lowercased variable name. The scope of this variables is global, so they can be used anywhere in your script (in opposite to local variables, which lives only within the given function).
$hello = 'hello' $world = 'world' puts $hello + ' ' + $world
Snake case is a practice of naming symbols which contains words or elements using underscode as a separator, for example:
server_name. In snake case, only lowercase characters are used.
Camel case uses uppercase letters for element separation, like:
Constant is a kind of variable, which should not be changed. Constant syntax is very similar to variable, but it must start with the capital letter. Most programmers are using only capital syntax for this:
NUMBER_ONE = 1 NUMBER_TWO = 2 SUM = NUMBER_ONE + NUMBER_TWO puts SUM
Be advised that in Ruby the constants are not very far from variables and you can change it - it is just giving a warning. In a session below, we've changed the constant content from "Hello, world" to "Hello, world!!!". Ruby gives the warning, but still allows to change the content.
HELLO_WORLD='Hello, world' #=> "Hello, world" HELLO_WORLD='Hello, world!!!' (irb):11: warning: already initialized constant HELLO_WORLD (irb):10: warning: previous definition of HELLO_WORLD was here #=> "Hello, world!!!" HELLO_WORLD #=> "Hello, world!!!"
Ruby is case sensitive which means that the symbol
serverOne is different than
Methods (aka functions, procedures) are defined using
def keyword, and should begin with lowercase character. Good practice is to use snake case for method names, just like for variables. The definition finishes with
end keyword. Here is a method to print well-know sentence:
def hello_world puts "Hello, world" end
If you run the script above, nothing will happen. This is because the method has been defined, but not invoked yet. You need to run it by simply write its name:
def hello_world puts "Hello, world" end hello_world # invoke method defined above
Notice that there is no need to use parenthesis in Ruby when they are not really required to avoid confusion. It is completely up to you, you may write
puts("Hello world") instead of
puts "Hello world".
It must be no space between method name and the parenthesis.
def hello_world() puts("Hello, world") end hello_world() # invoke method defined above
Methods may have the arguments, given as comma-separated list of names in parenthesis after the name. And the methods always return a value of last expression evaluated in its body. Or you can stop the flow and return the value using
return keyword. Consider two functions below:
def sum(first_number, second_number) first_number + second_number end the_sum = sum 2, 2 puts the_sum # prints '4' def another_sum(first_number, second_number) return first_number + second_number 2 + 2 # this line will never be evaluated end puts(another_sum(2, 3)) # prints '5'
sum, defined in lines 1 - 3, takes two arguments, adds them and returns value of this addition - the last expression. Fourth line invokes
sum function with arguments:
first_number = 2,
second_number = 2, gets the return value of 2 + 2 and assigns the value to the new variable
the_sum. The second method uses
return keyword to declare stricly where to exit the function and what to return. Notice the last expression
2 + 2 is not evaluated at all, because
return breaks method flow immediately.
Take a look at the line 11: here, the interpreter will evaluate the value of
another_sum(2, 2) and will pass the return value of it directly to the
puts method. There is no need to use intermediary variable, like in the first example.
Notice the methods in the 11th line are invoked with parenthesis. We did it by the reason: to avoid human ambiguity. From the interpreter point of view this construction is the same as
puts another_sum(2, 3) or even
puts another_sum 2, 3. In this case it is quite clear, but what if we want to pass two arguments to
puts (puts can take any number of arguments: it prints each of them in a new line)? For example, to print out the result of
another_sum 2, 3 and a number 5. In this case the proper expression is
puts(another_sum(2, 3), 5) or even
puts another_sum(2, 3), 5 but not
puts another_sum 2, 3, 5 - because in this case interpreter will try to find out the method
another_sum which tooks three arguments. To avoid it, use parenthesis in ambigious expressions, for code readability as well.
Here document is a construction known from the Unix Shell, allows to build a string from the multiple lines. Like in the Shell, you must specify a symbol used to identify the end of the string preceded by
<<. Notice there must be no space between
<< and the identifier.
str = <<EOF Hello world EOF puts str # prints 'Hello', newline, 'world'
Loading Ruby Files
There are two commands to load external Ruby source files (equivalent to Shell command
require. The first one just loads and executes the given Ruby source file, the second one is more complex: it is loading the file only once. The argument to
require command is a file name without ".rb" extention. It is searching for the file in the path given in global variable
PATH in the Shell). By default load path does not contain current directory, so you need to do
require './filename' if you want to load file from the current directory, or modify
The example below assumes there is a file
test.rb in a current directory contains only one line:
load 'test.rb' # load the file from current directory loaded #=> true load '/Users/turbo/test.rb' # load the file again loaded #=> true require './test' # require this file for the first time loaded #=> true require './test' # require again - file not loaded again #=> false puts $LOAD_PATH # content of the $LOAD_PATH /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/site_ruby/2.0.0 /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.1.0 /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/site_ruby /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/vendor_ruby/2.0.0 /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.1.0 /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/vendor_ruby /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0 /Users/turbo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/x86_64-darwin13.1.0