ZetCode Ruby tutorial.doc

Embed Size (px)

Citation preview

  • 7/27/2019 ZetCode Ruby tutorial.doc

    1/238

    ZetCode Ruby tutorial

    This is a Ruby tutorial. In this tutorial you will learn the Ruby language. The tutorial issuitable for beginners.

    Ruby

    Ruby is a dynamic, reflective, general-purpose object-oriented programming language. Theoriginal author is a Japanese programmer Yukihiro Matsumoto. Ruby first appeared in 1995.Ruby supports various programming paradigms. This includes object orientation, reflection,imperative and reflective programming.

    Ruby

    In this part of the Ruby tutorial, we will introduce the Ruby programming language.

    Goal

    The goal of this tutorial is to get you started with the Ruby programming language. Thetutorial covers the core of the Ruby language, including variables, expressions, collections,control structures and other core features. It also describes some more advanced concepts likeobject-oriented programming and regular expressions. It is not a complete coverage of thelanguage. The tutorial was created on Ubuntu Linux.

    Ruby

    Ruby is a dynamic, reflective, general-purpose object-oriented programminglanguage. The original author is a Japanese programmerYukihiro Matsumoto. Ruby firstappeared in 1995.

    Ruby supports various programming paradigms. This includes object orientation, reflection,imperative and reflective programming. Ruby language was influenced primarily by Perl,Smalltalk, Eiffel, and Lisp. Unlike languages like Java, C# or C, Ruby has no officialspecification. Instead the original C implementation of the Ruby language serves as a de factoreference. There are other implementations of the Ruby language like JRuby, IronRuby orMacRuby.

    The official web site is ruby-lang.org.

    Popularity

    There are hundreds of programming languages in use today. Ruby belongs to the mostpopular ones. The langpop.com and tiobe sites put Ruby around the 10th place. Ruby on

    1

    http://www.ruby-lang.org/http://langpop.com/http://www.tiobe.com/index.php/content/paperinfo/tpci/index.htmlhttp://www.ruby-lang.org/http://langpop.com/http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
  • 7/27/2019 ZetCode Ruby tutorial.doc

    2/238

    Rails, a very popular web application framework is the first killer application created inRuby.

    Interactive interpreter

    We can run Ruby statements in a script or in an interactive interpreter. In this tutorial, we willuse the interactive Ruby session to demonstrate some smaller code fragments. Larger codeexamples are to be put in Ruby scripts.

    $ irbirb(main):001:0> puts RUBY_VERSION1.8.7=> nil

    This is an example of the Ruby interactive session. We print the value of a specialRUBY_VERSION constant to the console. It is set to the version of the current Ruby in use.

    Ruby scripts

    We will have our first simple example of a Ruby script.

    #!/usr/bin/ruby

    # first.rb

    puts "This is Ruby"

    In this script, we print a message to the console.

    #!/usr/bin/ruby

    Every script in the UNIX starts with a shebang. The shebang is the first two characters in thescript: #!. The shebang is followed by the path to the interpreter, which will execute ourscript. The /usr/bin/ is the most common location for the Ruby interpreter. It could also belocated in /usr/local/bin/ or elsewhere.

    # first.rb

    Comments in Ruby are preceded by a # character.

    puts "This is Ruby"

    The puts method prints a string to the console.

    $ which ruby/usr/bin/ruby

    The path to the Ruby interpreter can be found using the which command.

    $ chmod +x first.rb

    $ ./first.rbThis is Ruby

    2

  • 7/27/2019 ZetCode Ruby tutorial.doc

    3/238

    We make the script executable with the chmod command. And execute it.

    Sources

    The following sources were used to create this tutorial:

    ruby-lang.org

    ruby-doc.org

    Ruby article on wikipedia.org

    ruby.runpaint.org

    In this part of the Ruby tutorial, we have introduced the Ruby language.

    Ruby lexical structure

    Computer languages, like human languages, have a lexical structure. A source code of aRuby program consists of tokens. Tokens are atomic code elements. In Ruby language wehave various lexical structures, such as comments, variables, literals, white spaces, operators,delimiters and keywords.

    Comments

    Comments are used by humans to clarify the source code. There are two types of commentsin Ruby. Single-line and multi-line comments. Single-line comments begin with the #character. Multi-line comments are put between the =begin and =end tokens.

    #!/usr/bin/ruby

    =begincomments.rbauthor Jan BodnarZetCode 2011

    =end

    # prints message to the terminalputs "Comments example"

    An example showing both types of comments. Comments are ignored by the Rubyinterpreter.

    =begincomments.rbauthor Jan BodnarZetCode 2011

    =end

    This is an example of a multi-line comment. The two tokens must start at the beginning of theline.

    3

    http://www.ruby-lang.org/http://ruby-doc.org/http://en.wikipedia.org/wiki/Ruby_(programming_language)http://ruby.runpaint.org/http://www.ruby-lang.org/http://ruby-doc.org/http://en.wikipedia.org/wiki/Ruby_(programming_language)http://ruby.runpaint.org/
  • 7/27/2019 ZetCode Ruby tutorial.doc

    4/238

    White space

    White space in Ruby is used to separate tokens and terminate statements in the source file. Itis also used to improve readability of the source code.

    if true thenputs "A message"

    end

    White spaces are required in some places. For example between the if keyword and the true

    keyword. Or between the puts method and the actual string. In other places, it is forbidden. It

    cannot be present in variable identifiers or language keywords.

    a=1b = 2c = 3

    The amount of space put between tokens is irrelevant for the Ruby interpreter. However, it isimportant to have one style throughout the project.

    #!/usr/bin/ruby

    x = 5 + 3puts x

    x = 5+ 3

    puts x

    x = 5 +3

    puts x

    A new line, a form of a white space, can be used to terminate statements.

    x = 5 + 3

    In the first case, we have one statement. The sum of the addition is assigned to the x variable.The variable holds 8.

    x = 5 + 3

    Now, there are two statements. The first statement is terminated with a newline. The xvariable is 5. There is another statement, +3, which has no effect.

    x = 5 +3

    Finally, we have one statement. The newline is preceded with a + binary operator, so theinterpreter expects another value. It looks on the second line. In this case, it takes both linesas one statement. The x variable is 8.

    $ ./whitespace.rb

    4

  • 7/27/2019 ZetCode Ruby tutorial.doc

    5/238

    858

    Output.

    Variables

    A variable is an identifier, which holds a value. In programming we say, that we assign avalue to a variable. Technically speaking, a variable is a reference to a computer memory,where the value is stored. In Ruby, a variable can hold a string, a number or various objects.Variables can be assigned different values over time.

    Variable names in Ruby are created from alfanumeric characters and underscore (_)character. A variable cannot begin with a number. The interpreter can easier distinguish

    between a literal number and a variable. Variable names cannot begin with a capital letter. If

    an identifier begins with a capital letter, it is considered to be a constant in Ruby.

    Valuevalue2company_name

    These are valid variable names.

    12Valexx$first-name

    These are examples of invalid variable names.

    Variable names may be preceded by two special characters, $ and @. They are used to createa specific variable scope.

    The variables are case sensitive. This means, that price, and pRice are two different

    identifiers.

    #!/usr/bin/ruby

    number = 10

    numBER = 11

    puts number, numBER

    In our script, we assign two numeric values to two identifiers. number and numBER are twodifferent variables.

    $ ./case.rb1011

    This is the output of the script.

    5

  • 7/27/2019 ZetCode Ruby tutorial.doc

    6/238

    Constants

    Constants are value holders, which hold only one value over time. An identifier with a firstuppercase letter is a constant in Ruby. In programming it is a convention to write allcharacters of a constant in uppercase.

    Unlike in other languages, Ruby does not enforce constants to have only one value over time.The interpreter only issues a warning if we assign a new value to an existing constant.

    #!/usr/bin/ruby

    Name = "Robert"AGE = 23

    Name = "Juliet"

    In the above example, we create two constants. One of the constants is redefined later.

    Name = "Robert"AGE = 23

    Two constants are created. When the identifier's name begins with an uppercase letter, thanwe have a constant in Ruby. By convention, constants are usually written in upperacse letters.

    Name = "Juliet"

    We redefine a constant. Which issues a warning.

    $ ./constants.rb./constants.rb:6: warning: already initialized constant Name

    Running the example.

    A literal

    A literal is a textual representation of a particular value of a type. Literal types includeboolean, integer, floating point, string, character, and date. Technically, a literal will beassigned a value at compile time, while a variable will be assigned at runtime.

    age = 29nationality = "Hungarian"

    Here we assign two literals to variables. Number 29 and string "Hungarian" are literals.

    #!/usr/bin/ruby

    require 'date'

    sng = truename = "James"job = nil

    weight = 68.5born = Date.parse("November 12, 1986")

    6

  • 7/27/2019 ZetCode Ruby tutorial.doc

    7/238

    puts "His name is #{name}"

    if sng == trueputs "He is single"

    elseputs "He is in a relationship"

    end

    puts "His job is #{job}"puts "He weighs #{weight} kilograms"puts "He was born in #{born}"

    In the above example, we have multiple literals. The bool literal may have value true or false.James is a string literal. The nil is an absense of a value. 68.5 is a floating point literal.Finally, the November 12, 1987 is a date literal.

    $ ./literals.rbHis name is James

    He is singleHis job isHe weighs 68.5 kilogramsHe was born in 1986-11-12

    This is the output of the literals.rb script.

    Blocks

    Ruby statements are often organized into blocks of code. A code block can be delimited using{ } characters ordo, end keywords.

    #!/usr/bin/ruby

    puts [2, -1, -4, 0].delete_if { |x| x < 0 }[1, 2, 3].each do |e|

    puts eend

    In the example, we show two code blocks.

    Flow control of Ruby code is often done with the if keyword. The keyword is followed by a

    block of code. In this case a block of code is delimited by then, end keywords, where thefirst keyword is optional.

    #!/usr/bin/ruby

    if true thenputs "Ruby language"puts "Ruby script"

    end

    In the above example, we have a simple block of code. It has two statements. The block isdelimited by then, end keywords. The then keyword can be omitted.

    7

  • 7/27/2019 ZetCode Ruby tutorial.doc

    8/238

    Sigils

    Sigils $, @ are special characters that denote a scope in a variable. The $ is used for globalvariables, @ for instance variables and @@ for class variables.

    $car_name = "Peugeot"@sea_name = "Black sea"@@species = "Cat"

    Sigils are always placed at the beginning of the variable identifier.

    Operators

    An operator is a symbol used to perform an action on some value. (answers.com)

    ! + - ~ * ** / %

    > & | ^== === != >= ><

  • 7/27/2019 ZetCode Ruby tutorial.doc

    9/238

    puts name; puts occupation

    The semicolon is used in Ruby to separate two statements in a Ruby source code.

    puts numbers[2]

    Delimiters can be used in different contexts. Here the square brackets are used to access anitem in the array.

    numbers.each { |i| puts i }

    Curly brackets are used to define a block of code. Pipes are used to define an element, whichis filled with a current array item for each loop cycle.

    puts ( 2 + 3 ) * 5

    Parentheses can be used to alter the evaluation of an expression.

    Keywords

    A keyword is a reserved word in the Ruby programming language. Keywords are used toperform a specific task in the computer program. For example, print a value to the console,do repetitive tasks or perform logical operations. A programmer cannot use a keyword as anordinary variable.

    alias and BEGIN begin break caseclass def defined? do else elsifEND end ensure false for ifin module next nil not orredo rescue retry return self superthen true undef unless until whenwhile yield

    This is a list of Ruby keywords.

    This was the Ruby lexical structure.

    Basics

    In this part of the Ruby tutorial, we will cover basic programming concepts of the Rubylanguage. We introduce the very basic programs. We will work with variables, constants and

    basic data types. We will read and write to the console; we will mention variableinterpolation.

    We start with a very simple code example.

    #!/usr/bin/ruby

    puts "This is Ruby"

    This is simple Ruby script. It will print "This is Ruby" message to the console.

    9

  • 7/27/2019 ZetCode Ruby tutorial.doc

    10/238

    #!/usr/bin/ruby

    This is a path to the Ruby interpreter, which will execute the script.

    puts "This is Ruby"

    The puts is a Ruby keyword, which prints its argument to the terminal. In our case the

    argument is a string message, delimeted by double qoutes.

    $ ./first.rbThis is Ruby

    Executing the script gives the above output.

    We can read values from the terminal. (Terminal and console are synonyms)

    #!/usr/bin/ruby

    print "What is your name? "name = gets

    puts "Hello #{name}"

    The second program will read a value from a console and print it.

    print "What is your name? "

    The print keyword prints a message to the console. The difference between the print andputs keywords is that the print keyword does not start a new line. The puts keyword

    automatically starts a new line.

    name = gets

    Here we read an input from the user and store it in the name variable. The gets is a method,

    which in our case reads a line from the terminal. It is one of the methods that we have at ourdisposal by default.

    puts "Hello #{name}"

    In this code line, we perform variable interpolation. Variable interpolation is replacingvariables with their values inside string literals. Another names for variable interpolation are:variable substitution and variable expansion.

    $ ./name.rbWhat is your name? JanHello Jan

    This is the output of the second program.

    10

  • 7/27/2019 ZetCode Ruby tutorial.doc

    11/238

    Ruby code can be run from the command line. This is inspired by Perl one-liners, wheresmall fragments of code are run to do some petit tasks.

    $ ruby -e "puts RUBY_VERSION"1.9.3

    The -e option tells Ruby to execute Ruby code specified on the line and not to search for aRuby file name. Our example prints the version of the Ruby interpreter to the terminal.

    Ruby interpreter has a -c option which checks the syntax of the code. If this option is used,the code is not executed. If there is no syntax error, Ruby will print "Syntax OK" to thestandard output.

    #!/usr/bin/ruby

    class Being endm = Test.newp m

    In the above example, there is a syntax error. If we put class and end keywords on one line,we must also use the semicolon ; character.

    $ ruby -c syntax_check.rbsyntax_check.rb:3: syntax error, unexpected keyword_end, expecting '

  • 7/27/2019 ZetCode Ruby tutorial.doc

    12/238

    We provide three numbers as command line arguments and these are printed to the console.

    In the following example, we wil print all arguments and also the script name.

    #!/usr/bin/ruby

    puts $0puts $*

    The $0 global variable contains the name of the script being executed. Global variables inRuby begin with the $ character. The $* is another global variable. It is a synonym for theARGV variable. It contains command line arguments given for the current script.

    $ ./args2.rb Ruby Python Perl./args2.rbRuby

    PythonPerl

    The args2.rb script receives three strings. The name of the script and the three arguments areprinted to the terminal.

    Variables and constants

    A variable is a place to store data. A variable has a name and a data type. Data types aredifferent types of values. Integers, strings and floating point numbers are examples of datatypes. Ruby is a dynamic language. This means that we do not have to (and cannot) declare a

    variable to be of a certain data type. Instead, the Ruby interpreter determines the data type atthe moment of the assignment. Moreover, a variable can contain different values and alsodifferent types of values over time. This differs from languages that are strongly types, likeJava, C or Pascal. Unlike variables, constants (should) retain their values. Once initialized,they cannot be modified. In Ruby however, it is possible to change the value of a constant. Insuch a case a warning is issued.

    #!/usr/bin/ruby

    city = "New York"name = "Paul"; age = 35

    nationality = "American"

    puts cityputs nameputs ageputs nationality

    city = "London"

    puts city

    In the above example, we work with four variables.

    city = "New York"

    12

  • 7/27/2019 ZetCode Ruby tutorial.doc

    13/238

    We assign a string value to the city variable. The variable is dynamically created.

    name = "Paul"; age = 35

    We create two more variables. We can put two statements into one line. For readability,

    however, each statement should be on a separate line.

    puts cityputs nameputs ageputs nationality

    We print the values of the variables to the terminal.

    city = "London"

    We assign a new value to the city variable.

    $ ./variables.rbNew YorkPaul35AmericanLondon

    Output of the example.

    Constants As we already said, constants store one value over the time. Unlike in otherlanguages, this rule is however not enforced in Ruby.

    #!/usr/bin/ruby

    WIDTH = 100HEIGHT = 150

    var = 40puts var

    var = 50puts var

    puts WIDTHWIDTH = 110puts WIDTH

    In this example, we declare two constants and one variable.

    WIDTH = 100HEIGHT = 150

    Constants in ruby begin with capital letter. It is a common practice to write all characters inuppercase letters.

    var = 40

    13

  • 7/27/2019 ZetCode Ruby tutorial.doc

    14/238

    puts var

    var = 50

    We declare and initialize a variable. Later, we assign a new value to the variable. It is legal.

    WIDTH = 110

    We assign a new value to a constant. Constants should not be modified, once they arecreated. Otherwise it has no meaning to create a constant. The Ruby interpreter will issue awarning.

    $ ./constants.rb4050100./constants.rb:13: warning: already initialized constant WIDTH110

    Output of the script.

    Variable interpolation

    Variable interpolation is replacing variables with their values inside string literals. Othernames for variable interpolation are variable substitution and variable expansion.

    #!/usr/bin/ruby

    age = 34name = "William"

    puts "#{name} is #{age} years old"

    In Ruby, strings are immutable. We cannot modify an existing string. Variable interpolationhappens during string creation.

    age = 34name = "William"

    Here we declare two variables.

    puts "#{name} is #{age} years old"

    The string message has double quotes as its boundaries. When we put a variable namebetween the #{ and } characters, the variable is interpolated: that is, replaced with its value.

    $ ./interpolation.rbWilliam is 34 years old

    Output.

    This chapter covered some basics of the Ruby language.

    14

  • 7/27/2019 ZetCode Ruby tutorial.doc

    15/238

    Variables in Ruby

    In this part of the Ruby tutorial, we will examine variables in more detail.

    A variable is a place to store data. Each variable is given a unique name. There are somenaming conventions which apply to variable names. Variables hold objects. More precisely,they refer to a specific object located in computer memory. Each object is of certain datatype. There are built-in data types and there are custom-built data types. Ruby belongs to thefamily of dynamic languages. Unlike strongly typed languages like Java, C or Pascal,dynamic languages do not declare a variable to be of certain data type. Instead of that, theinterpreter determines the data type at the moment of the assignment. Variables in Ruby cancontain different values and different types of values over time.

    #!/usr/bin/ruby

    i = 5puts ii = 7puts i

    The term variable comes from the fact that variables, unlike constants, can take differentvalues over time. In the example above there is a variable called i. First it is assigned a value5, later a different value 7.

    Naming conventions

    Ruby, like any other programming language, has some naming conventions for variableindentifiers.

    Ruby is a case sensitive language. It means that age and Age are two different variablenames. Most languages are case sensitive. BASIC is an exception; it is a case insensitivelanguage. While we can create different names by changing the case of the characters, this

    practice is not recommended.

    #!/usr/bin/ruby

    i = 5p i

    I = 7p I

    The code example defines two variables. I and i. They hold different values.

    ./case.rb57

    Output of the case.rb example.

    15

  • 7/27/2019 ZetCode Ruby tutorial.doc

    16/238

    Variable names in Ruby can be created from alpfanumeric characters and the underscore (_)character. A variable cannot begin with a number. This makes it easier for the interpreter todistinguish a literal number from a variable. Variable names cannot begin with a capitalletter. If an identifier begins with a capital letter, it is considered to be a constant in Ruby.

    #!/usr/bin/ruby

    name = "Jane"placeOfBirth = "Bratislava"placeOfBirth = "Kosice"favorite_season = "autumn"

    n1 = 2n2 = 4n3 = 7

    p name, placeOfBirth, favorite_seasonp n1, n2, n3

    In this script, we show a few valid variable names.

    Variable names should be meaningful. It is a good programming practice to choosedescriptive names for variables. The programs are more readable then.

    #!/usr/bin/ruby

    name = "Jane"place_of_birth = "Bratislava"occupation = "student"

    i = 5while i > 0 do

    puts namei -= 1

    end

    The script shows three descriptive variable names. The place_of_birth is more descriptive toa programmer than e.g. pob. It is generally considered OK to choose simple variable names inloops.

    Sigils

    Variable identifiers can start with special characters also called sigils. A sigil is a symbolattached to an identifier. Variable sigils in Ruby denote variable scope. This is in contrast toPerl, where sigils denote data type. The Ruby variable sigils are $ and @.

    #!/usr/bin/ruby

    tree_name = "pine"$car_name = "Peugeot"@sea_name = "Black sea"@@species = "Cat"

    p local_variablesp global_variables.include? :$car_name

    16

  • 7/27/2019 ZetCode Ruby tutorial.doc

    17/238

    p self.instance_variablesp Object.class_variables

    We have four variables with different scopes. A scope is the range in which a variable can bereferenced. We use special built-in methods to determine the scope of the variables.

    tree_name = "pine"

    A variable without a sigil is a local variable. A local variable is valid only locally: e.g., insidea method, block or a module.

    $car_name = "Peugeot"

    Global variables start with $ character. They are valid everywhere. The use of globalvariables should be limited in programs.

    @sea_name = "Black sea"

    A variable name starting with a @ sigil is an instance variable. This variable is valid inside anobject.

    @@species = "Cat"

    Finally we have a class variable. This variable is valid for all instances of a specific class.

    p local_variables

    The local_variables gives an array of all local variables defined in a specific context. Our

    context is Ruby toplevel.

    p global_variables.include? :$car_name

    Similarly, the global_variables produces an array of globals. We do not print all globals to

    the terminal, because there are many of them. Each Ruby script starts with a bunch ofpredefined variables. Instead of that, we call the include? method of the array to check if our

    global is defined in the array. Also note that we are referencing variables with their symbols.(Symbols start with a colon character.)

    p self.instance_variables

    The self pseudo variable points to the receiver of the instance_variables method. The

    receiver in our case is the main, the Ruby toplevel execution area.

    p Object.class_variables

    Finally we have an array of class variables. The main is an instance of the Object class.

    $ ./sigils.rb[:tree_name]true

    [:@sea_name][:@@species]

    17

  • 7/27/2019 ZetCode Ruby tutorial.doc

    18/238

    Output of the example. We see symbolic names of the variables.

    Local variables

    Local variables are variables that are valid within a local area of a Ruby source code. This

    area is also referred to as local scope. Local variables exist within the definition of a Rubymodule, method, class.

    #!/usr/bin/ruby

    def method1x = 5p x

    end

    method1

    p x

    We have a method called method1, which has one variable. The variable is local. This meansthat it is valid only within the method definition. We can refer to the x variable only betweenthe method name and the end keyword.

    def method1x = 5p x

    end

    This is the definition of the method1 method. Inside the method, we create a local x variable.

    We print the value of the variable to the terminal.

    method1

    The method is called.

    p x

    We try to refer to a local variable outside the definition of the method. This leads to aNameError. The Ruby interpreter cannot find such identifier.

    $ ./locals.rb5./locals.rb:11:in `': undefined local variableor method `x' for main:Object (NameError)

    Running the example gives the above output.

    The following example is a slight modification of a previous example.

    #!/usr/bin/ruby

    x = 5

    18

  • 7/27/2019 ZetCode Ruby tutorial.doc

    19/238

    def method1x = 10p x

    end

    method1

    p x

    We have two x variables. One is defined inside the method1 and the other one is definedoutside. They are two distinct local variables. They do not clash with each other.

    x = 5

    We have created a local x variable, which holds value 5. The variable is valid in the localscope of the main execution area. It is not valid inside the method1.

    def method1x = 10p x

    end

    Inside the definition of the method1 a new local variable x is defined. It has value 10. It existsin the body of the method1 method. After the end keyword it ceases to exist.

    $ ./locals2.rb105

    Output.

    If a method takes parameters, a local variable is created for each of these parameters.

    #!/usr/bin/ruby

    def rectangle_area a, bputs local_variablesreturn a * b

    end

    puts rectangle_area 5, 6

    We have a method definition, which takes two values. The method returns the area of arectangle.

    def rectangle_area a, bputs local_variablesreturn a * b

    end

    The rectangle_area method takes two parameters. They are the sides of a rectangle, for which

    we calculate the area. Two local variables are automatically created for identifiers a and b.We call the local_variablesmethod to see what local variables we have in the method.

    19

  • 7/27/2019 ZetCode Ruby tutorial.doc

    20/238

    puts rectangle_area 5, 6

    Here we pass two values to the method rectangle_area. The values will be assigned to twolocal variables, created inside the method.

    $ ./parameters.rbab30

    The output shows three things. The first two are the names of the local variables within therectangle_area method. The third is the calculated area of the given rectangle.

    A method may be defined inside another method. The inner methods have their own localvariables.

    #!/usr/bin/ruby

    def method1

    def method2

    def method3m5, m6 = 3puts "Level 3"puts local_variables

    end

    m3, m4 = 3puts "Level 2"puts local_variablesmethod3

    end

    m1, m2 = 3puts "Level 1"puts local_variablesmethod2

    end

    method1

    In this Ruby script, we create three methods. The method2 and method3 are inner methods.The method2 is defined inside the method1 and the method3 is defined inside method2. Eachmethod's local variables are only accessible in the method in which they were defined.

    $ ./lms.rbLevel 1m1m2Level 2m3m4Level 3m5

    20

  • 7/27/2019 ZetCode Ruby tutorial.doc

    21/238

    m6

    From the output we can see that method1 has two local variables, m1 and m2. The innermethod2 has local variables m3, m4. The method3, the innermost method, has local variablesm5, m6.

    The last example of this section will present several demonstrations of a local scope.

    module ModuleMm1, m2 = 4

    puts "Inside module"puts local_variables

    end

    def method1v, w = 3puts "Inside method"puts local_variables

    end

    class Somex, y = 2puts "Inside class"puts local_variables

    end

    method1

    t1, t2 = 7

    puts "Inside toplevel"puts local_variables

    In the code example, we create local variables inside a module, method, class and toplevel.The local_variables is a method of the Kernel module that returns all current local

    variables.

    module ModuleM

    m1, m2 = 4puts "Inside module"puts local_variables

    end

    A module is a collection of methods and constants. We create two local variables m1 and m2.

    def method1v, w = 3puts "Inside method"puts local_variables

    end

    Two local variables, v and w, are created in method1.

    21

  • 7/27/2019 ZetCode Ruby tutorial.doc

    22/238

    class Somex, y = 2puts "Inside class"puts local_variables

    end

    The x, y local variables are created inside the definition of the Some class.

    t1, t2 = 7

    Finally, two local variables that belong to the Ruby toplevel's local scope are created.

    $ ./locals3.rbInside modulem1m2Inside classx

    yInside methodvwInside toplevelt1t2

    The output shows local variables for each local scope.

    Global variables

    Global variables are valid everywhere in the script. They start with a $ sigil in Ruby.

    The use of global variables is discouraged. Global variables easily lead to many programmingerrors. Global variables should be used only when there is a reason to do so. Instead of globalvariables, programmers are advised to use local variables whenever possible.

    #!/usr/bin/ruby

    $gb = 6

    module ModuleMputs "Inside module"puts $gb

    end

    def method1puts "Inside method"puts $gb

    end

    class Someputs "Inside class"puts $gb

    end

    22

  • 7/27/2019 ZetCode Ruby tutorial.doc

    23/238

    method1

    puts "Inside toplevel"puts $gbputs global_variables.include? :$gb

    In the example we have a global variable $gb. We show that the variable can be referenced ina module, method, class and a toplevel. The global variable $gb is valid in all these entities.

    $gb = 6

    A global variable $gb is created; it has value 6.

    module ModuleMputs "Inside module"puts $gb

    end

    Inside a module's definition we print the global variable's value.

    def method1puts "Inside method"puts $gb

    end

    Inside the defition of a method we print the value of the global variable.

    class Some

    puts "Inside class"puts $gbend

    Inside the defition of a class we print the value of the global variable.

    puts $gbputs global_variables.include? :$gb

    Finally, in the toplevel execution area we print the global variable's value and whether thevariable is in the array produced by the global_variables method.

    $ ./globals.rbInside module6Inside class6Inside method6Inside toplevel6true

    The output of the example confirms that the global variable is accessible everywhere.

    23

  • 7/27/2019 ZetCode Ruby tutorial.doc

    24/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    25/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    26/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    27/238

    Pseudo variables

    Ruby has a few variables which are called pseudo variables. They are different from regularvariables. We cannot assign values to pseudo variables.

    The self is the receiver of the current method. The nil is the sole instance of the NilClass.It represents the absense of a value. The true is the sole instance of the TrueClass. It

    represents boolean true. The false is a sole instance ofFalseClass. It represents boolean

    false.

    The true and false are values of a boolean datatype. From another point of view, they areinstances of specific classes. This is because everything in Ruby is an object. This looks likeunnecessarily complicated. But it is the consequence of the aforementioned Ruby idiom.

    #!/usr/bin/ruby

    p selfp nilp truep false

    p self.classp nil.classp true.classp false.class

    This is an example of pseudo variables. We print all four pseudo variables with the p method.

    Then we find out the class name for all of them.

    p self

    In this context, the self pseudo variable returns the main execution context.

    $ ./pseudo.rbmainniltruefalseObjectNilClass

    TrueClassFalseClass

    Example output.

    In the second example of this section, we will further look at the self.

    #!/usr/bin/ruby

    class Someputs self

    end

    27

  • 7/27/2019 ZetCode Ruby tutorial.doc

    28/238

    class Otherputs self

    end

    puts self

    As we have said, the self references the receiver of the current method. The above exampleshows three examples of different receivers.

    class Someputs self

    end

    The receiver is the class called Some.

    class Otherputs self

    end

    Here is another receiver: a class named Other.

    puts self

    And the third receiver is the Ruby toplevel.

    $ ./pseudoself.rbSomeOthermain

    Example output.

    The last example of the section will present other three pseudo variables.

    #!/usr/bin/ruby

    if trueputs "This message is shown"

    end

    if falseputs "This message is not shown"

    end

    p $namep $age

    The above example shows true, false and nil pseudo variables at work.

    if trueputs "This message is shown"

    end

    The true is used in boolean expression. The message is always printed.

    28

  • 7/27/2019 ZetCode Ruby tutorial.doc

    29/238

    if falseputs "This message is not shown"

    end

    This message is never printed. The condition is not met. In the boolean expression we alwaysget a negative value.

    p $namep $age

    If global values are referenced and have not been initialized, they contain the nil pseudo

    variable. It stands for the absence of a value.

    $ ./pseudo2.rbThis message is shownnilnil

    Output of the pseudo2.rb Ruby script.

    Predefined variables

    Ruby has plenty of predefined global variables. This is a heritage of Perl language. Ruby wasinfluenced strongly by Perl. They are accessible when the Ruby script starts. We have a fewexamples for the predefined Ruby variables.

    #!/usr/bin/ruby

    print "Script name: ", $0, "\n"print "Command line arguments: ", $*, "\n"

    puts "Process number of this script: #{$$}"

    Three predefined variables have been used. $0, $* and $$. The $0 stores the current scriptname. The $* variable stores command-line arguments. And the $$ stores the PID (processid) of the script.

    $ ./predefined.rb 1 2 3Script name: ./predefined.rbCommand line arguments: ["1", "2", "3"]

    Process number of this script: 3122

    Sample output.

    The $? global variable stores the exit status of the last executed child process.

    #!/usr/bin/ruby

    system 'echo "Ruby"'puts $?

    %x[exit '1']puts $?

    29

  • 7/27/2019 ZetCode Ruby tutorial.doc

    30/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    31/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    32/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    33/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    34/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    35/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    36/238

    puts :name.classputs :name.frozen?

    puts (1..6).classputs (1..6).include? 4

    In the above example we use literal notation to create a Fixnum, Strings, Arrays, Symbolsand Ranges.

    4.times { puts "Ruby" }

    We can immediately call a method on an integer literal. This line prints a "Ruby" string fourtimes to the terminal.

    puts "Ruby".sizeputs "Ruby".downcase

    We call two methods on a String object created with a string literal.

    puts [1, 2, 3].include? 3puts [1, 2, 3].empty?

    Here we create two Array objects using array literal notations. We check if a specific numberis part of the array with the include? method. The empty? method checks if the array object

    is empty or not.

    puts :name.classputs :name.frozen?

    Two methods of the Symbol object are called. The symbol is created with a symbol literal,which starts with a colon.

    puts (1..6).classputs (1..6).include? 4

    Two Range objects are created using the range literal. We call two methods on those objects.The class method returns the name of the class and the include? method checks if a given

    number is part of the range.

    $ ./literals.rbRubyRubyRubyRuby4rubytruefalseSymbolfalseRangetrue

    Example output.

    36

  • 7/27/2019 ZetCode Ruby tutorial.doc

    37/238

    Object hierarchy

    In many object-oriented languages objects form a hierarchy. Ruby has and object hierarchytoo. It is a tree-like hierarchy, where we have parent objects and child objects. Objects inheritdata and behaviour from their parent objects. At the top of the hierarchy there is the root

    object. It is called the Object. Each object in Ruby has at least one parent. In other words,every object inherits from the basic Object object.

    According to the official Ruby documentation, Object is the root of Ruby's class hierarchy.

    Its methods are available to all classes unless explicitly overridden.

    #!/usr/bin/ruby

    puts 4.is_a? Objectputs "Ruby".is_a? Objectputs [2, 3].is_a? Objectputs :name.is_a? Objectputs (1..2).is_a? Object

    In the above code example we demonstrate that all objects inherit from the root Object

    puts 4.is_a? Object

    We use the is_a? method to check if a number is a specific type: in other words, if it inherits

    from a given object type.

    $ ./mother.rbtrue

    truetruetruetrue

    All methods return true, which means that all objects inherit from the mother object.

    The inheritance hierarchy may be quite complex even for the very basic Ruby objects.

    #!/usr/bin/ruby

    puts 6.class

    puts 6.is_a? BasicObjectputs 6.is_a? Objectputs 6.is_a? Numericputs 6.is_a? Integerputs 6.is_a? Fixnum

    puts 6.is_a? Bignumputs 6.is_a? String

    In this example we shed some light on the inheritance hierarchy of a small numerical value.

    puts 6.class

    37

  • 7/27/2019 ZetCode Ruby tutorial.doc

    38/238

    We find out what kind of object is the number value 6. The line prints Fixnum to the console.

    puts 6.is_a? BasicObjectputs 6.is_a? Objectputs 6.is_a? Numericputs 6.is_a? Integer

    puts 6.is_a? Fixnum

    All the above lines return true. Number 6 is a Fixnum. From the Ruby documentation we find

    out that the four other objects are parents of the Fixnum object.

    puts 6.is_a? Bignumputs 6.is_a? String

    The above two objects are not parents for the 6 value.

    $ ./inheritance.rb

    Fixnumtruetruetruetruetruefalsefalse

    Output of the example.

    We will finish this section with an example, demonstrating inheritance of custom userobjects.

    #!/usr/bin/ruby

    class Being

    def to_s"This is Being"

    end

    def get_id9

    endend

    class Living < Being

    def to_s"This is Living"

    endend

    l = Living.new

    puts l

    puts l.get_idputs l.is_a? Being

    38

  • 7/27/2019 ZetCode Ruby tutorial.doc

    39/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    40/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    41/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    42/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    43/238

    The boolean values are presented by true and false objects.

    p "Ruby".class

    This is the string.

    p 1.classp 4.5.classp 3_463_456_457.class

    These are the numbers.

    p :age.class

    This is a symbol, a data type specific to Ruby.

    p [1, 2, 3].class

    p h.class

    These are two containers, the array and the hash.

    $ ./types.rbTrueClassFalseClassStringFixnumFloatBignumSymbol

    ArrayHash

    The program lists classes that belong to Ruby data types.

    Boolean values

    There is a duality built in our world. There is a Heaven and Earth, water and fire, jing andjang, man and woman, love and hatred. This is the 'boolean' nature of our existence. In Rubythe boolean data type can have one of the two values: true or false. Boolean is a fundamentaldata type: one that is very common in computer programs.

    Happy parents are waiting a child to be born. They have chosen a name for both possibilities.If it is going to be a boy, they have chosen John. If it is going to be a girl, they have chosenVictoria.

    #!/usr/bin/ruby

    # kid.rb

    bool = [true, false]

    male = bool[rand(2)]

    43

  • 7/27/2019 ZetCode Ruby tutorial.doc

    44/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    45/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    46/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    47/238

    @is = trueend

    def say

    "I am being"end

    end

    b = Being.new

    p b.method :sayp b.instance_variable_get :@is

    A Being class is defined. The class has a custom instance variable @is and a say method.These two entities are stored using symbols by Ruby.

    p b.method :say

    The method method looks up a receiver method with a given name in the b object. We lookfor a :say symbol.

    p b.instance_variable_get :@is

    We use instance_variable_get to check if @is is an instance variable of the b object.

    Internally the variable is stored as an :@is symbol.

    $ ./symbols4.rb#true

    Generated output.

    All symbols are stored in a symbol table. In the next example, we look at the table. Theall_symbolsmethod of a Symbol class returns an array of all symbols from the table.

    #!/usr/bin/ruby

    def info"info method"

    end

    @v = "Ruby"@@n = "16"

    p Symbol.all_symbols.include? :infop Symbol.all_symbols.include? :@vp Symbol.all_symbols.include? :@@n

    A method, an instance variable and a class variable are created in a Ruby script. We check ifthese entities are stored in a symbol table.

    p Symbol.all_symbols.include? :info

    We check if the :info symbol is in the symbol table. The line returns true.

    47

  • 7/27/2019 ZetCode Ruby tutorial.doc

    48/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    49/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    50/238

    total = baskets * apples_in_basket

    puts "There are total of #{total} apples"

    In our program, we count the total amount of apples. We work with integers.

    $ ./apples.rbThere are total of 384 apples

    The output of the program.

    Big numbers are difficult to read. If we have a number like 245342395423452, we find itdifficult to read quickly. Outside computers, big numbers are separated by spaces or commas.For readability, Ruby allows integers to contain underscores. Underscores in integers areignored by the Ruby interpreter.

    #!/usr/bin/ruby

    p 23482345629p 23_482_345_629

    p 23482345629 == 23_482_345_629

    The example demonstrates this use of underscores.

    p 23482345629 == 23_482_345_629

    This line shows that the two numbers are equal. It prints true.

    $ ./underscore.rb2348234562923482345629true

    Example output.

    Floating point numbers

    Floating point numbers represent real numbers in computing. Real numbers measure

    continuous quantities like weight, height or speed. In Ruby, decimal numbers are objects ofthe Float or a BigDecimal class. The BigDecimal class, a Ruby core class, is part of Ruby's

    standard library. In addition, we can use Rational objects too.

    We need to understand that decimal numbers are not precise. The official Rubydocumentation clearly says that float objects represent inexact real numbers.

    #!/usr/bin/ruby

    p 15.4p 0.3455

    p -343.4563

    p 12.5.class

    50

  • 7/27/2019 ZetCode Ruby tutorial.doc

    51/238

    p -12.5.classp (5.0 / 2).class

    p 5.fdiv 2p 12.to_f

    In the above program, we work with floating point values.

    p 15.4p 0.3455p -343.4563

    Here we print three decimal values. Decimal numbers have a decimal point character.

    p 12.5.classp -12.5.classp (5.0 / 2).class

    The above code lines show the types of the numbers. All are floats. Integer division appliedon at least one Float produces a Float too.

    p 5.fdiv 2p 12.to_f

    Here we create floating point values by using the floating point fdiv division method and the

    conversion to_f method.

    $ ./decimals.rb15.4

    0.3455-343.4563FloatFloatFloat2.512.0

    Output.

    By default, a decimal number is shown with a maximum 16 numbers after the decimal point.

    We can control the format of floating point values with the sprintf orprintf methods.

    #!/usr/bin/ruby

    p 1/3.0p 1.fdiv 2

    puts sprintf "%.4f" % (1/3.0)puts sprintf "%.7f" % (5/3.0)

    Formatting decimal numbers.

    p 1/3.0p 13.fdiv 4

    51

  • 7/27/2019 ZetCode Ruby tutorial.doc

    52/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    53/238

    #!/usr/bin/ruby

    require 'bigdecimal'

    sum = 0

    1000.times dosum = sum + 0.0001end

    p sum

    sum = BigDecimal.new("0")

    1000.times dosum = sum + BigDecimal.new("0.0001")

    end

    puts sum.to_s('F')puts sum.to_s('E')

    In this simple example, we compare the precision of a Float compared to a BigDecimal.

    require 'bigdecimal'

    The BigDecimal class must be imported.

    sum = 0

    1000.times do

    sum = sum + 0.0001end

    p sum

    We form a loop, where we add a small floatig point value to a sum variable. In the end, therewill be a small inaccuracy.

    sum = BigDecimal.new("0")

    1000.times dosum = sum + BigDecimal.new("0.0001")

    end

    We do the same loop with the BigDecimal values.

    puts sum.to_s('F')puts sum.to_s('E')

    The sum is printed in floting point and engineering notation.

    $ ./bigdecimal.rb0.100000000000001840.1

    0.1E0

    53

  • 7/27/2019 ZetCode Ruby tutorial.doc

    54/238

    The output shows that the computing with BigDecimal is more precise than with Floats.

    Let's say a sprinter for 100m ran 9.87s. What is his speed in km/h?

    #!/usr/bin/ruby

    distance = 0.1time = 9.87 / 3600

    speed = distance / time

    puts "The average speed of a sprinter is #{speed} km/h"

    In this example, it is necessary to use floating point values.

    distance = 0.1

    100m is 0.1 km.

    time = 9.87 / 3600

    9.87s is 9.87/60*60 h

    speed = distance / time

    To get the speed, we divide the distance by the time.

    $ ./speed.rbThe average speed of a sprinter is 36.4741641337386 km/h

    This is the output of the speed.rb script.

    Rational Numbers

    Ruby supports rational numbers. A rational number is an exact number. Using rationalnumbers we avoid rounding errors. In Ruby, a rational number is an object of the Rational

    class. We can create rational numbers with a special to_r method from some objects.

    A rational number is any number that can be expressed as a fraction of two integers a/b ,where b!=0. Since b may be equal to 1, every integer is a rational number.

    #!/usr/bin/ruby

    puts 2.to_rputs "23".to_rputs 2.6.to_r

    p Rational 0p Rational 1/5.0p Rational 0.5

    This example shows a few rational numbers.

    54

  • 7/27/2019 ZetCode Ruby tutorial.doc

    55/238

    puts 2.to_r

    Here we convert a 2 integer to 2/1 rational number using the to_r method.

    p Rational 0.5

    We create a rational number with the Rational class.

    $ ./rational.rb2/123/15854679515581645/2251799813685248(0/1)(3602879701896397/18014398509481984)(1/2)

    Output of the example.

    The nil value

    Ruby has a special value nil. It is an absence of a value. The nil is a singleton object of a

    NilClass. There is only one nil; we cannot have more of it.

    #!/usr/bin/ruby

    puts nilp nil

    p $val

    p [1, 2, 3][4]

    p $val1 == $val2

    An example with the nil value.

    puts nilp nil

    We print the nil value to the console. The puts method prints an empty string; the p method

    prints 'nil' string.

    p $val

    When we refer to a global variable that was not set, we get the nil value.

    p [1, 2, 3][3]

    In this code line, we refer to the fourth element of a three-element array. We get nil. Many

    methods in Ruby return nil for invalid values.

    p $val1 == $val2

    55

  • 7/27/2019 ZetCode Ruby tutorial.doc

    56/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    57/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    58/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    59/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    60/238

    Here we use a split method of the String class to convert a string to an array.

    $ ./stringconv.rb1213.0(12/1)

    (13+0i):JaneArray

    And this is what we get.

    The next small example shows array hash conversions.

    #!/usr/bin/ruby

    h = {:de => "Germany", :sk => "Slovakia"}p h.to_a

    a = [:de, "Germany", :sk, "Slovakia",:hu, "Hungary", :no, "Norway"]

    p Hash[*a]

    In the example code, we create a hash and covert it to array. Then we create an array andconvert it to a hash.

    h = {:de => "Germany", :sk => "Slovakia"}p h.to_a

    A hash is created and converted to an array using the to_a method.

    a = [:de, "Germany", :sk, "Slovakia",:hu, "Hungary", :no, "Norway"]

    p Hash[*a]

    An array is created and converted to a hash. The asterisk in this context is a splat operator. Itis one of the Ruby idioms taken from Perl. It splits an array into a few variables.

    $ ./h2a.rb[[:de, "Germany"], [:sk, "Slovakia"]]

    {:de=>"Germany", :sk=>"Slovakia", :hu=>"Hungary", :no=>"Norway"}

    Output.

    In this part of the Ruby tutorial, we covered data types and their conversions.

    Strings in Ruby

    In this part of the Ruby tutorial, we will work with string data in more detail.

    Strings are one of the most important data types in computer languages. That is why wededicate a whole chapter to working with strings in Ruby.

    60

  • 7/27/2019 ZetCode Ruby tutorial.doc

    61/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    62/238

    #!/usr/bin/ruby

    puts "one two three four"puts "one\ntwo\nthree\nfour"

    One of the most common escape sequences is the newline character \n. It is available in many

    programming languages. The next character after the newline will appear on the new line.

    $ ./newline.rbone two three fouronetwothreefour

    Words after newline characters appear on new lines in the output of the about script.

    The r, b and t characters are normal alphabetical characters. When preceded with a \character, they have a special meaning.

    #!/usr/bin/ruby

    puts " bbb\raaa"puts "Joan\b\b\bane"puts "Towering\tinferno"

    In the above example, we use three different escape characters.

    puts " bbb\raaa"

    The carriage return \r is a control character for end of line return to beginning of line. Beforethe string is printed to the console, it is first processed. The escape sequence causes the aaacharacters to be placed before the bbb characters. The output is aaabbb.

    puts "Joan\b\b\bane"

    The \b control character is a backspace. It deletes a preceding character. The string printed tothe console is 'Jane' not 'Joan'.

    puts "Towering\tinferno"

    Finally, the \t escape sequence places a tab space between the two words.

    $ ./escapes.rbaaabbbJaneTowering inferno

    Output of the example.

    The backslash character \ is a special character used to create escape sequences. When thereis a need to print a backslash itself, it is preceded with another backslash. Its default meaning

    62

  • 7/27/2019 ZetCode Ruby tutorial.doc

    63/238

    is escaped and it is printed. The single and double quotes are used to delimit strings in Ruby.In order to print them, they are preceded by \ too.

    #!/usr/bin/ruby

    puts "The special character \\"puts "The special character \'"puts "The special character \""

    In this simple script, we print all three characters to the terminal.

    $ ./specials.rbThe special character \The special character 'The special character "

    Output.

    Accessing string elements

    It is possible to access string elements in Ruby. For this we use the square brackets []. Insidethe brackets, we can put strings, indexes or ranges.

    #!/usr/bin/ruby

    msg = "Ruby language"

    puts msg["Ruby"]puts msg["Python"]

    puts msg[0]puts msg[-1]

    puts msg[0, 3]puts msg[0..9]puts msg[0, msg.length]

    This code example shows, how we can access parts of a string.

    msg = "Ruby language"

    Here is the string, that we will be accessing.

    puts msg["Ruby"]

    In this code line we test, whether string 'Ruby' is a substring of the msg string. If it is true,then the string that we are looking for is returned.

    puts msg[0]

    The characters of the string can be accessed by their index. The numbers start from 0. Inother words, the 0 is the index of the first character. The msg[0] returns the first character of

    the string, namely R.

    63

  • 7/27/2019 ZetCode Ruby tutorial.doc

    64/238

    puts msg[-1]

    Here we access the last character of the string. The -1 stands for the last index of the string.

    puts msg[0, 3]

    Two indexes separated by a comma return characters starting from the first index and endingwith the second index, excluded.

    puts msg[0..9]

    A range operator can be used as well. Here we print the first ten characters of the msg string.

    puts msg[0, msg.length]

    This line returns the whole string. The msg.length returns the size of the string.

    $ ./access.rbRuby

    ReRubRuby languRuby language

    Output of the example.

    Multiline stringsIn many programming languages creating multiline strings requires additional effort. This isespecially true in Visual Basic. In Ruby, multiline strings are created easily.

    #!/usr/bin/ruby

    puts "I hear Mariachi static on my radioAnd the tubes they glow in the darkAnd I'm there with her in EnsenadaAnd I'm here in Echo Park"

    puts %/Carmelita hold me tighterI think I'm sinking downAnd I'm all strung out on heroinOn the outskirts of town/

    puts

  • 7/27/2019 ZetCode Ruby tutorial.doc

    65/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    66/238

    message = "%s is %d years old" % [name, age]

    We build a string before we use it. The %s and %d are formatting characters that expect astring and a number, respectively. The values are provided in square brackets after the %character.

    Concatenating strings

    Concatenating strings is creating one string from multiple strings.

    #!/usr/bin/ruby

    lang = "Ruby" + " programming" + " languge"puts lang

    lang = "Python" " programming" " language"puts lang

    lang = "Perl"

  • 7/27/2019 ZetCode Ruby tutorial.doc

    67/238

    Freezing strings

    In Java or C#, the strings are immutable. This means, that we cannot modify an existingstring. We can only create a new string out of an existing one. In Ruby, the strings are notimmutable by default.

    String objects in Ruby have a freeze method, which makes them immutable.

    #!/usr/bin/ruby

    msg = "Jane"msg

  • 7/27/2019 ZetCode Ruby tutorial.doc

    68/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    69/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    70/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    71/238

    ruby = "Ruby programming language"

    puts ruby.upcaseputs ruby.downcaseputs ruby.capitalizeputs ruby.swapcase

    Ruby has four methods for character case. The upcase method returns a copy of the string in

    which all characters are in uppercase. The downcase method returns a copy of the string in

    which all characters are in downcase. The capitalize method returns a copy of string with

    the first character converted to uppercase and the remainder to lowercase. Finally, theswapcase method returns a copy of the string where the uppercase letters are converted to

    downcase and vice versa.

    $ ./rubylang.rbRUBY PROGRAMMING LANGUAGEruby programming language

    Ruby programming languagerUBY PROGRAMMING LANGUAGE

    Output.

    Next we present two Ruby string methods: start_with? and end_with?. Both methods

    return a boolean true or false. They determine whether a string starts or ends with a specificstring, respectively.

    #!/usr/bin/ruby

    ws1 = "zetcode.com"ws2 = "www.gnome.org"

    puts ws1.start_with? "www."puts ws2.start_with? "www."

    puts

    puts ws1.end_with? ".com"puts ws2.end_with? ".com"

    This is an example for the aforementioned methods.

    puts ws1.start_with? "www."

    Here we check if a string starts with a "www." prefix. It does not, so the output to the consoleis a boolean false.

    puts ws1.end_with? ".com"

    We check whether the ws1 string variable ends with a ".com" suffix. It does, so we see a truein the console.

    $ ./startend.rbfalsetrue

    71

  • 7/27/2019 ZetCode Ruby tutorial.doc

    72/238

    truefalse

    Output.

    In the following example, we will deal with the inspect method. The method returns a raw

    string, surrounded by quote marks, with special characters not interpreted. It is useful whenwe want to examine what characters form the string.

    #!/usr/bin/ruby

    msg = "Jane\t17\nThomas\t23"

    puts msgputs msg.inspect

    An example of the inspect string method.

    msg = "Jane\t17\nThomas\t23"

    This is a string with some special characters.

    puts msgputs msg.inspect

    In the first case, the special characters are interpreted. There is a tab and a newline between

    string parts. In the second case, we get the string in a raw format.

    $ ./inspectmethod.rbJane 17Thomas 23"Jane\t17\nThomas\t23"

    Output of the example.

    The chomp method returns a new string with the record separator removed from the end of the

    string. The default separator is the newline (\n).

    #!/usr/bin/ruby

    print "Are you sure to download? (Yes/No) "

    response = gets

    if (response.downcase == "yes")puts "Downloaded"

    elseputs "Download cancelled"

    end

    puts response.inspect

    72

  • 7/27/2019 ZetCode Ruby tutorial.doc

    73/238

    In the above script, we get an input from the user. We react to the user response.

    $ ./chomp.rbAre you sure to download? (Yes/No) YesDownload cancelled"Yes\n"

    The script does not work correctly. The reason becomes clear when we consider whatinspect returns. The input from the user is ended with an enter key. The newline character is

    included in the response variable too. And "yes" does not equal to "yes\n". To correct thescript, we use the chomp method. It removes the newline from the variable.

    #!/usr/bin/ruby

    print "Are you sure to download? (Yes/No) "

    response = gets

    if (response.downcase.chomp == "yes")puts "Downloaded"

    elseputs "Download cancelled"

    end

    puts response.inspect

    This is the corrected example.

    if (response.downcase.chomp == "yes")

    Here we process the input before it is compared with the "yes" string. The chomp method

    removes the newline character.

    $ ./chomp.rbAre you sure to download? (Yes/No) YesDownloaded"Yes\n"

    Now the example works correctly.

    Formatting strings

    Ruby has format specifiers. A format specifier determines how the string is going to looklike. It begins with a % character. Format specifiers are put inside single or double quotes.

    The format specifier has the following fields:

    %[flags][field width][precision]conversion specifier

    Fields in square brackets are optional.

    A conversion specifier specifies how the data is going to be converted into displayable form.

    #!/usr/bin/ruby

    73

  • 7/27/2019 ZetCode Ruby tutorial.doc

    74/238

    puts "There are %d oranges in the basket." % 12puts "There are %d oranges and %d apples in the basket." % [12, 10]

    Here is an example of some format specifiers.

    puts "There are %d oranges in the basket" % 12

    When we use the %d notation inside a string, we expect a number at that point. The d is aconversion specifier for decimal numbers. The number is given after the % character.

    puts "There are %d oranges and %d apples in the basket" % [12, 10]

    We can use multiple format specifiers inside a string. Each begins with a % character.Multiple values are placed between [] characters and separated by comma character.

    $ ./formatspecifiers.rb

    There are 12 oranges in the basket.There are 12 oranges and 10 apples in the basket.

    Output of the example.

    In the following example, we will cover some basic conversion specifiers.

    #!/usr/bin/ruby

    puts "There are %d apples." % 5

    puts "I can see %i oranges." % 3puts "The width of iPhone 3G is %f mm." % 62.1puts "This animal is called a %s" % "rhinoceros."

    We have conversion specifiers for integers, floating point numbers and strings.

    puts "There are %d apples." % 5puts "I can see %i oranges." % 3

    Both d an i can be used for integers.

    puts "The width of iPhone 3G is %f mm." % 62.1

    The f is a conversion specifier for floating point values. By default, floats have six decimalplaces.

    puts "This animal is called a %s" % "rhinoceros."

    The s character is used for strings.

    $ ./basicspecifiers.rbThere are 5 apples.I can see 3 oranges.The width of iPhone 3G is 62.100000 mm.This animal is called a rhinoceros.

    74

  • 7/27/2019 ZetCode Ruby tutorial.doc

    75/238

    Output of the example.

    Next we have a practical example of using a format specifier.

    #!/usr/bin/ruby

    website = "zetcode.com"

    website.each_char do |c|print "#{c} has ASCII code %d\n" % c.ord

    end

    In this example, we go through all characters of a string and print their ASCII values to theterminal.

    website.each_char do |c|

    print "#{c} has ASCII code %d\n" % c.ordend

    The each_char method passes each character of a website string to the block, one character

    per cycle, with current character stored in c variable. We get the ASCII code of the characterusing the ord method, which returns the ordinal of a one character string.

    $ ./character.rbz has ASCII code 122e has ASCII code 101t has ASCII code 116c has ASCII code 99

    o has ASCII code 111d has ASCII code 100e has ASCII code 101. has ASCII code 46c has ASCII code 99o has ASCII code 111m has ASCII code 109

    Output of the example.

    Numbers can be displayed in various forms. The conversion specifier can be used to format

    numbers.

    #!/usr/bin/ruby

    # decimalputs "%d" % 300

    # hexadecimalputs "%x" % 300

    # octalputs "%o" % 300

    # binaryputs "%b" % 300

    75

  • 7/27/2019 ZetCode Ruby tutorial.doc

    76/238

    # scientificputs "%e" % (5/3.0)

    In the above example, we print numbers in decimal, hexadecimal, octal, binary and scientificformats.

    # hexadecimalputs "%x" % 300

    The x conversion specifier is used to transform a number into a hexadecimal format.

    # binaryputs "%b" % 300

    The x conversion specifier is used to transform a number into a binary format.

    $ ./various.rb30012c4541001011001.666667e+00

    Output.

    Precision is a field in the format specifier. It is specified as a number following a decimalpoint. It has a different meaning for an integer, a floating point number and for a string. Whenused with integers, it indicates the minimum number of digits to be printed. If the number hasfewer digits than the precision, zeros are prefixed. The default precision for integers is 1,meaning that no zeros are filled. When used with a float number, the precision is the numberof digits displayed after the decimal point. Finally, with strings, the precision is the maximumnumber of characters printed.

    #!/usr/bin/ruby

    puts 'Height: %f %s' % [172.3, 'cm']puts 'Height: %.1f %s' % [172.3, 'cm']

    puts "%d" % 16puts "%.5d" % 16

    puts "%s" % "zetcode"puts "%.5s" % "zetcode"

    In this example, we will work with the precision field.

    puts 'Height: %f %s' % [172.3, 'cm']puts 'Height: %.1f %s' % [172.3, 'cm']

    172.3 is a floating point number. If no precision is specified, there will be 6 decimal places

    after a decimal point. In our case, there will be 5 zeros. The .1 in the second code line is theprecision. For a floating point value, it reduces the number of decimal places to 1.

    76

  • 7/27/2019 ZetCode Ruby tutorial.doc

    77/238

    puts "%d" % 16puts "%.5d" % 16

    The default precision for integers is 1. In the second line, we have specified precision .5,which adds (prepends) 3 zeros to the 16 number.

    puts "%s" % "zetcode"puts "%.5s" % "zetcode"

    The first line prints all characters of the string. The second line prints only five of them. Twocharacters are dropped.

    $ ./precision.rbHeight: 172.300000 cmHeight: 172.3 cm1600016zetcodezetco

    Output.

    Field width specifies the minimum width of the data to display. It is a number, which comesbefore the decimal point, if it is present. If the output is shorter, then it is padded with spacesand it is right aligned. If we put a minus sign before the field width, it is left aligned. If theoutput is longer than the field width, it is displayed in full.

    #!/usr/bin/ruby

    puts "%d" % 1puts "%d" % 16puts "%d" % 165puts "%d" % 1656puts "%d" % 16567

    puts "%10d" % 1puts "%10d" % 16puts "%10d" % 165puts "%10d" % 1656puts "%10d" % 16567

    In the first case, we print five numbers without specifying the field width. The width of theoutput is equal to the number of the characters being displayed. In the second case we have afield width of 10. Each of the 5 outputs has a minimum length of 10 characters. The numbersare right aligned.

    puts "%d" % 1puts "%d" % 16

    We print two numbers. The width of the output has 1, 2 characters, respectively.

    puts "%10d" % 1puts "%10d" % 16

    77

  • 7/27/2019 ZetCode Ruby tutorial.doc

    78/238

    Here the length in both cases is 10 characters. The two numbers are padded with 9 and 8spaces in the given order.

    $ ./fieldwidth.rb116165165616567

    116

    1651656

    16567

    We can see that in the second case the numbers are right aligned.

    Theflagqualifier modifies the format's behaviour.

    The # flag adds a 0b, 0, and 0x prefix to binary, octal and hexadecimal formats respectively.It adds a decimal point to the floating point values, even if the number of decimal places have

    been restricted by the precision.

    #!/usr/bin/ruby

    puts "%#b" % 231puts "%#x" % 231puts "%#o" % 231

    puts "%.0e" % 231puts "%#.0e" % 231

    puts "%.0f" % 231puts "%#.0f" % 231

    In the code example, we use the x flag.

    puts "%#b" % 231puts "%#x" % 231puts "%#o" % 231

    The decimal 231 is printed in binary, octal, and hexadecimal formats. The # flags adds aprefix for them.

    puts "%.0e" % 231puts "%#.0e" % 231

    Here, the .0 precision supresses the decimal places of a number. However, when used with a# flag, the decimal point is displayed, even though there are no decimal digits.

    $ ./flags1.rb0xe7

    0b111001110347

    78

  • 7/27/2019 ZetCode Ruby tutorial.doc

    79/238

    2e+022.e+02231231.

    Output.

    The + flag adds a plus sign for positive decimal numbers. For binary, octal and hexadecimalnegative numbers it adds a minus sign and uses an absolute value.

    #!/usr/bin/ruby

    puts "%d" % 231puts "%+d" % 231puts "%d" % -231puts "%+d" % -231

    puts "%b" % -231puts "%o" % -231puts "%x" % -231

    puts "%+b" % -231puts "%+o" % -231puts "%+x" % -231

    An example demonstrating the + flag of the format specifier.

    puts "%d" % 231puts "%+d" % 231

    Usually, positive numbers have their sign omitted. If we want to show a plus sign for positivenumbers, we specify the + flag.

    puts "%d" % -231puts "%+d" % -231

    The + flag has no effect on negative numbers. The output is the same.

    puts "%b" % -231puts "%o" % -231puts "%x" % -231

    Binary, octal and hexadecimal numbers have their own way to create negative numbers.

    puts "%+b" % -231puts "%+o" % -231puts "%+x" % -231

    If we specify the + flag for these negative numbers, we transform a number to a differentformat and add a minus sign. There is no special way of representing negative numbers.

    $ ./flags2.rb

    231+231

    79

  • 7/27/2019 ZetCode Ruby tutorial.doc

    80/238

    -231-231..100011001..7431..f19-11100111

    -347-e7

    Output of the example.

    Here we introduce the 0 flag and the - flag. The 0 flag causes the number to be padded withzeros instead of spaces. The - flag makes the output left aligned.

    #!/usr/bin/ruby

    puts "%010d" % 1puts "%010d" % 16puts "%010d" % 165puts "%010d" % 1656puts "%010d" % 16567

    puts "%-10d" % 1puts "%-10d" % 16puts "%-10d" % 165puts "%-10d" % 1656puts "%-10d" % 16567

    Example.

    puts "%010d" % 1puts "%010d" % 16

    Numbers will be padded with zeros.

    puts "%-10d" % 1puts "%-10d" % 16

    The number, being shorter than the field width, is aligned. And the - flag makes it leftaligned.

    $ ./fieldwidth2.rb00000000010000000016000000016500000016560000016567116165165616567

    Ouput of the example.

    80

  • 7/27/2019 ZetCode Ruby tutorial.doc

    81/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    82/238

    Category Symbol

    Resolution, access operators :: .

    Array operators [ ] [ ]=

    Exponentiation **

    Not, complement, unary plus, minus ! ~ + -

    Multiply, divide, modulo * / %

    Addition, substraction + -

    Shift operators >

    Bitwise and &

    Bitwise or, logical or ^ |

    Relational operators > >= <

  • 7/27/2019 ZetCode Ruby tutorial.doc

    83/238

    puts aputs -(a)puts -(-(a))

    The minus sign changes the sign of a value.

    $ ./sign.rb1-11

    This is the output of the example.

    The assignment operator

    The assignment operator = assigns a value to a variable. A variable is a placeholder for a

    value. In mathematics, the = operator has a different meaning. In an equation, the = operatoris an equality operator. The left side of the equation is equal to the right one.

    x = 1puts x # prints 1

    Here we assign a number to the x variable.

    x = x + 1puts x # prints 2

    The previous expression does not make sense in mathematics. But it is legal in programming.The expression adds 1 to the x variable. The right side is equal to 2 and 2 is assigned to x.

    3 = x;

    This code example results in syntax error. We cannot assign a value to a literal.

    Resolution, member access operators

    These two operators have the highest precedence level in the hierarchy of the operators.Which means, that they are always evaluated first.

    #!/usr/bin/ruby

    class MyMathPi = 3.1415926535

    end

    module PeopleName = "People"

    end

    puts MyMath::Piputs People::Name

    83

  • 7/27/2019 ZetCode Ruby tutorial.doc

    84/238

    In the first example, we present the :: namespace resolution operator. It allows to access aconstant, module, or class defined inside another class or module. It is used to providenamespaces so that method and class names don't conflict with other classes by differentauthors.

    class MyMathPi = 3.1415926535

    end

    module PeopleName = "People"

    end

    We have a simple module and a class. Each has one constant defined.

    puts MyMath::Piputs People::Name

    We use the :: operator to access constants from both.

    $ ./resolution.rb3.1415926535People

    This is the output of the resolution.rb program.

    The dot . operator is a member access operator. It is used to call methods of objects.

    #!/usr/bin/ruby

    class Person

    def initialize name, age@name = name@age = age

    end

    def info"#{@name} is #{@age} years old"

    endend

    p = Person.new "Jane", 17puts p.info

    puts "ZetCode".reverse

    In our example, we have two objects. One user defined and one predefined. We use the dotoperator to work with these objects.

    p = Person.new "Jane", 17puts p.info

    In these two lines, the dot operator calls two methods: new and info.

    84

  • 7/27/2019 ZetCode Ruby tutorial.doc

    85/238

    puts "ZetCode".reverse

    A string is a built-in object, which has a reverse method. This is being called.

    $ ./memberaccess.rbJane is 17 years oldedoCteZ

    This is the output of the example.

    Concatenating strings

    In Ruby the + operator is also used to concatenate strings. When an operator is used indifferent contexts differently, we say that it is overloaded.

    #!/usr/bin/ruby

    puts "Return " + "of " + "the " + "King"puts "Return ".+"of ".+ "the ".+"King"

    We join three strings together using string concatenation operator.

    puts "Return " + "of " + "the " + "King"

    We join four strings using + operator.

    puts "Return ".+"of ".+ "the ".+"King"

    Under the hood, the + operator is a Ruby method. The string literal is an object. We call amethod of an object using the access (.) operator.

    $ ./catstrings.rbReturn of the KingReturn of the King

    And this is what we get, when we run the catstrings.rb program.

    Increment, decrement operators

    Ruby has no such operators.

    x++;x = x + 1;...y--;y = y - 1;

    These are increment, decrement operators in C.

    If you are familiar with Java, C, C++, you know these operators. They are not available inRuby. Python language does not have them too.

    85

  • 7/27/2019 ZetCode Ruby tutorial.doc

    86/238

    Arithmetic operators

    The following is a table of arithmetic operators in Ruby.

    Symbol Name

    + Addition

    - Subtraction

    * Multiplication

    / Division

    % Remainder

    ** Power

    In the next example, we use arithmetic operations.

    #!/usr/bin/ruby

    a = 10b = 11c = 12

    puts a + b + cputs c - aputs a * bputs c / 3puts c % aputs c ** a

    In the preceding example, we use addition, subtraction, multiplication, division and

    remainder operations. This is all familiar from the mathematics.

    puts c % a

    The % operator is called the remainder or the modulo operator. It finds the remainder ofdivision of one number by another. For example, 9 % 4, 9 modulo 4 is 1, because 4 goes into9 twice with a remainder of 1.

    $ ./arithmetic.rb332

    1104261917364224

    This is the output of the example.

    Next we will show the distinction between integer and floating point division.

    #!/usr/bin/ruby

    puts 5 / 2

    86

  • 7/27/2019 ZetCode Ruby tutorial.doc

    87/238

  • 7/27/2019 ZetCode Ruby tutorial.doc

    88/238

    The quo method performs the most accurate division. It returns a float if either operand is

    float, otherwise rational.

    $ ./otherdivision.rb22.55/22.5

    Boolean operators

    In Ruby, we have the following logical operators. Boolean operators are also called logical.

    Symbol Name

    && logical and

    || logical or

    ! negation

    Boolean operators deal with truth values. Ruby has additional alternative boolean operators.These are and, or & not. They do the same except for the thing that they have a lower

    precedence level. This duplicity is taken from the Perl language, where there was a need forboolean operators with a lower precedence.

    #!/usr/bin/ruby

    x = 3y = 8

    puts x == yputs y > x

    if y > x thenputs "y is greater than x"

    end

    Many expressions result in a boolean value. Boolean values are used in conditionalstatements.

    puts x == yputs y > x

    Relational operators always result in a boolean value. These two lines print false and true.

    if y > x thenputs "y is greater than x"

    end

    The body of the if statement is executed only if the condition inside the parentheses is met.

    The x > y returns true, so the message "y is greater than x" is printed to the terminal.

    The next example shows the logical and operator.

    88

  • 7/27/2019 ZetCode Ruby tutorial.doc

    89/238

    #!/usr/bin/ruby

    puts true && trueputs true && falseputs false && trueputs false && false

    The and operator evaluates to true only if both operands are true.

    $ ./andoperator.rbtruefalsefalsefalse

    Only one of the expressions results in true.

    The logical or || operator evaluates to true if either of the operands is true.

    #!/usr/bin/ruby

    puts true || trueputs true || falseputs false || trueputs false || false

    If one of the sides of the operator is true, the outcome of the operation is true.

    $ ./oroperator.rbtruetruetruefalse

    Three expressions result in a boolean true.

    The negation operator ! makes true false and false true.

    #!/usr/bin/ruby

    puts !0puts !1puts !trueputs !false

    puts ! (4

  • 7/27/2019 ZetCode Ruby tutorial.doc

    90/238

    truetruetrue

    This is the output of the example.

    The ||, and && operators are short circuit evaluated. Short circuit evaluation means that the

    second argument is only evaluated if the first argument does not suffice to determine thevalue of the expression: when the first argument of the logical and evaluates to false, theoverall value must be false; and when the first argument of logical or evaluates to true, theoverall value must be true. Short circuit evaluation is used mainly to improve performance.

    An example may clarify this a bit more.

    #!/usr/bin/ruby

    def oneputs "Inside one"false

    end

    def twoputs "Inside two"true

    end

    puts "Short circuit"

    if one && twoputs "Pass"

    end

    puts "##############################"

    if two || oneputs "Pass"

    end

    We have two methods in the example. They are used as operands in boolean expressions. Wewill see if they are called or not.

    if one && twoputs "Pass"

    end

    The one method returns false. The short circuit && does not evaluate the second method. It isnot necessary. Once an operand is false, the result of the logical conclusion is always false.Only "Inside one" is only printed to the console.

    puts "##############################"

    if two || oneputs "Pass"

    end

    90

  • 7/27/2019 ZetCode Ruby tutorial.doc

    91/238

    In the second case, we use the || operator and use the two method as the first operand. In thiscase, "Inside two" and "Pass" strings are printed to the terminal. It is again not necessary toevaluate the second operand, since once the first operand evaluates to true, the logical or isalways true.

    $ ./shortcircuit.rbShort circuitInside one##############################Inside twoPass

    We see the result of the shortcircuit.rb program.

    Relational Operators

    Relational operators are used to compare values. These operators always result in booleanvalue.

    Symbol Meaning

    < less than

    greater than

    >= greater than or equal to

    Relational operators are also called comparison operators.

    #!/usr/bin/ruby

    p 3 < 4p 3 > 5p 3 >= 3

    The 3 < 4 expression returns true, since 3 is smaller than 4. The 3 > 5 expression returns

    false because it is not true that 3 is greater than 5.

    Bitwise operators

    Decimal numbers are natural to humans. Binary numbers are native to computers. Binary,octal, decimal or hexadecimal symbols are only notations of the same number. Bitwiseoperators work with bits of a binary number.

    Symbol Meaning

    ~ bitwise negation

    ^ bitwise exclusive or

    & bitwise and

    | bitwise or

    > right shift

    91

  • 7/27/2019 ZetCode Ruby tutorial.doc

    92/238

    Bitwise operators are seldom used in higher level languages like Ruby.

    #!/usr/bin/ruby

    puts ~ 7 # prints -8puts ~ -8 # prints 7

    puts 6 & 3 # prints 2puts 3 & 6 # prints 2

    puts 6 ^ 3 # prints 5puts 3 ^ 6 # prints 5

    puts 6 | 3 # prints 7puts 3 | 6 # prints 7

    puts 6 1 # prints 3puts 1 >> 6 # prints 0

    In the above code example, we show all 6 operators.

    puts ~ 7 # prints -8puts ~ -8 # prints 7

    The bitwise negation operatorchanges each 1 to 0 and 0 to 1. The operator reverts all bits ofa number 7. One of the bits also determines, whether the number is negative or not. If wenegate all the bits one more time, we get number 7 again.

    puts 6 & 3 # prints 2puts 3 & 6 # prints 2

    The bitwise and operatorperforms bit-by-bit comparison between two numbers. The resultfor a bit position is 1 only if both corresponding bits in the operands are 1.

    puts 6 ^ 3 # prints 5puts 3 ^ 6 # prints 5

    The bitwise exclusive or operatorperforms bit-by-bit comparison between two numbers. Theresult for a bit position is 1 if one or the other (but not both) of the corresponding bits in theoperands is 1.

    puts 6 | 3 # prints 7puts 3 | 6 # prints 7

    The bitwise or operatorperforms bit-by-bit comparison between two nubmers. The result fora bit position is 1 if either of the corresponding bits in the operands is 1.

    puts 6 1 # prints 3puts 1 >> 6 # prints 0

    92

  • 7/27/2019 ZetCode Ruby tutorial.doc

    93/238

    The bitwise shift operators shift bits to the right or left. These operators are also calledarithmetic shift.

    Compound assignment operators

    The compound assignment operators consist of two operators. They are shorthand operators.

    #!/usr/bin/ruby

    a = 0

    a = a + 1a += 1puts a

    b = 0

    b = b - 8b -= 8puts b

    The += and -= compound operators are one of these shorthand operators. They are lessreadable than the full expressions but experienced programmers often use them.

    a = a + 1a += 1

    These two lines do the same; they add 1 to the a variable.

    Other compound operators are:

    -= *= **= /= %= &= |= =

    Operator precedence

    The operator precedence tells us which operators are evaluated first. The precedence level isnecessary to avoid ambiguity in expressions.

    What is the outcome of the following expression? 28 or 40?

    3 + 5 * 5

    Like in mathematics, the multiplication operator has a higher precedence than additionoperator. So the outcome is 28.

    (3 + 5) * 5

    To change the order of evaluation, we can use parentheses. Expressions inside parenthesesare always evaluated first.

    #!/usr/bin/ruby

    puts 3 + 5 * 5

    93

  • 7/27/2019 ZetCode Ruby tutorial.doc

    94/238

    puts (3 + 5) * 5

    puts ! true | trueputs ! (true | true)

    In this code example, we show some common expressions. The outcome of each expression

    is dependent on the precedence level.

    puts 3 + 5 * 5

    This line prints 28. The multiplication operator has a higher precedence than addition. Firstthe product of 5*5 is calculated. Then 3 is added.

    puts ! true | true

    In this case, the negation operator has a higher precedence. First, the first true value isnegated to false, than the | operator combines false and true, which gives true in the end.

    $ ./precedence.rb2840truefalse

    Associativity

    Sometimes the precedence is not satisfactory to determine the outcome of an expression.There is another rule called associativity. The associativity of operators determines the order

    of evaluation of operators with thesame precedence level.

    9 / 3 * 3

    What is the outcome of this expression? 9 or 1? The multiplication, deletion and the modulooperator are left to right associated. So the expression is evaluated this way: (9 / 3) * 3

    and the result is 9.

    Arithmetic, boolean, relational and bitwise operators are all left to right associated.

    On the other hand, the assignment operator is right associated.

    a = b = c = d = 0print a, b, c, d # prints 0000

    If the association was left to right, the previous expression would not be possible.

    The compound assignment operators are right to left associated.

    j = 0j *= 3 + 1puts j

    94

  • 7/27/2019 ZetCode Ruby tutorial.doc

    95/238

    You might expect the result to be 1. But the actual result is 0, because of the associativity.The expression on the right is evaluated first and then the compound assignment operator isapplied.

    Range operators

    Ruby has two range operators. They are used to quickly create a range of objects. Most oftena range of numbers or letters.

    The .. range operator (two dots) creates an inclusive range. The ... operator (three dots)creates an exclusive range, where the high value of the range is excluded.

    #!/usr/bin/ruby

    p (1..3).to_ap (1...3).to_a

    p ('a' .. 'l').to_a

    In the example, we use both range operators to create a range of numbers and characters.

    p (1..3).to_ap (1...3).to_a

    These two lines create two ranges using both range operators. The range objects areconverted to arrays. The first range has values 1, 2 and 3 while the second range has values 1and 2.

    p ('a' .. 'l').to_a

    Here we use the .. range operator to create an array of letters from 'a' to 'l'.

    $ ./range.rb[1, 2, 3][1, 2]["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]

    This is the example output.

    The ternary operator

    The ternary operator (?:) is a conditional operator. It is a convenient operator for cases wherewe want to pick up one of two values, depending on the conditional expression.

    cond-exp ? exp1 : exp2

    If cond-exp is true, exp1 is evaluated and the result is returned. If the cond-exp is false, exp2is evaluated and its result is returned.

    #!/usr/bin/ruby

    age = 32

    95

  • 7/27/2019 ZetCode Ruby tutorial.doc

    96/238

    adult = age >= 18 ? true : false

    if adult thenp