Jump to content

Ruby Programming/Print version

From Wikibooks, open books for an open world


Overview

| Installing Ruby →


Ruby is an object-oriented scripting language originally developed by Yukihiro Matsumoto (also known as Matz). The main website of the Ruby programming language is ruby-lang.org. Development began in February 1993 and the first alpha version of Ruby was released in December 1994. It was developed as an alternative to scripting languages like Perl and Python.[1] Ruby borrows heavily from Perl and the class library is essentially an object-oriented reorganization of Perl's functionality. Ruby also borrows from Lisp and Smalltalk. While Ruby does not borrow many features from Python, reading the code for Python helped Matz develop Ruby.[1]

MacOS comes with Ruby already installed. Most Linux distributions either come with Ruby preinstalled or allow you to easily install Ruby from the distribution's repository of free software. You can also download and install Ruby on Windows. The more technically adept can download the Ruby source code[2] and compile it for most operating systems, including Unix, DOS, BeOS, OS/2, Windows, and Linux.[3]

Features

Ruby combines features from Perl, Smalltalk, Eiffel, Ada, Lisp, and Python.[3]

Object Oriented

Ruby goes to great lengths to be a purely object oriented language. Every value in Ruby is an object, even the most primitive things: strings, numbers and even true and false. Every object has a class and every class has one superclass. At the root of the class hierarchy is the class BasicObject, from which all other classes, including Object, inherit.

Every class has a set of methods which can be called on objects of that class. Methods are always called on an object — there are no “class methods”, as there are in many other languages (though Ruby does a great job at faking them).[citation needed]

Every object has a set of instance variables which hold the state of the object. Instance variables are created and accessed from within methods called on the object. Instance variables are completely private to an object. No other object can see them, not even other objects of the same class, or the class itself. All communication between Ruby objects happens through methods.

Mixins

In addition to classes, Ruby has modules. A module has methods, just like a class, but it has no instances. Instead, a module can be included, or “mixed in,” to a class, which adds the methods of that module to the class. This is very much like inheritance but far more flexible because a class can include many different modules. By building individual features into separate modules, functionality can be combined in elaborate ways and code easily reused. Mix-ins help keep Ruby code free of complicated and restrictive class hierarchies.

Dynamic

Ruby is a very dynamic programming language. Ruby programs aren’t compiled, in the way that C or Java programs are. All of the class, module and method definitions in a program are built by the code when it is run. A program can also modify its own definitions while it’s running. Even the most primitive classes of the language like String and Integer can be opened up and extended. Rubyists call this monkey patching and it’s the kind of thing you can’t get away with in most other languages.

Variables in Ruby are dynamically typed, which means that any variable can hold any type of object. When you call a method on an object, Ruby looks up the method by name alone — it doesn't care about the type of the object. This is called duck typing and it lets you make classes that can pretend to be other classes, just by implementing the same methods.

Singleton Classes

When I said that every Ruby object has a class, I lied. The truth is, every object has two classes: a “regular” class and a singleton class. An object’s singleton class is a nameless class whose only instance is that object. Every object has its very own singleton class, created automatically along with the object. Singleton classes inherit from their object’s regular class and are initially empty, but you can open them up and add methods to them, which can then be called on the lone object belonging to them. This is Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant.

Metaprogramming

Ruby is so object oriented that even classes, modules and methods are themselves objects! Every class is an instance of the class Class and every module is an instance of the class Module. You can call their methods to learn about them or even modify them, while your program is running. That means that you can use Ruby code to generate classes and modules, a technique known as metaprogramming. Used wisely, metaprogramming allows you to capture highly abstract design patterns in code and implement them as easily as calling a method.

Flexibility

In Ruby, everything is malleable. Methods can be added to existing classes without subclassing, operators can be overloaded, and even the behavior of the standard library can be redefined at runtime.

Variables and scope

You do not need to declare variables or variable scope in Ruby. The name of the variable automatically determines its scope.

  • x is a local variable (or something other than a variable).
  • $x is a global variable.
  • @x is an instance variable.
  • @@x is a class variable.

Blocks

Blocks are one of Ruby’s most unique and most loved features. A block is a piece of code that can appear after a call to a method, like this:

laundry_list.sort do |a,b|
  a.color <=> b.color
end

The block is everything between the do and the end. The code in the block is not evaluated right away, rather it is packaged into an object and passed to the sort method as an argument. That object can be called at any time, just like calling a method. The sort method calls the block whenever it needs to compare two values in the list. The block gives you a lot of control over how sort behaves. A block object, like any other object, can be stored in a variable, passed along to other methods, or even copied.

Many programming languages support code objects like this. They’re called closures and they are a very powerful feature in any language, but they are typically underused because the code to create them tends to look ugly and unnatural. A Ruby block is simply a special, clean syntax for the common case of creating a closure and passing it to a method. This simple feature has inspired Rubyists to use closures extensively, in all sorts of creative new ways.

Advanced features

Ruby contains many advanced features.

You can also write extensions to Ruby in C or embed Ruby in other software.

References

  1. a b Bruce Stewart (November 29, 2001). "An Interview with the Creator of Ruby". O'Reilly. Retrieved 2006-09-11.
  2. "Download Ruby". Retrieved 2006-09-11.
  3. a b "About Ruby". Retrieved 2006-09-11.

Installing Ruby

← Overview | Ruby editors →


The first step to get started in Ruby development is setting up your local environment. Due to differences between various operating systems we will cover multiple of them. If you are already able to use a terminal emulator and know how to install Ruby yourself, you can skip this chapter (after you installed Ruby). Otherwise we will guide you through the process of installing Ruby on your computer.

Terminal emulators

Knowing how to use a terminal emulator is very useful if you are programming. Usually it will provide the most straightforward access to commands and applications instead of hiding it behind graphical interfaces. On the other hand they are often daunting to beginners since they are often perceived to require a deep understanding of a computer when in fact often only knowing the very basics is already enough to get started.

Unix-like operating systems

Screenshot of xterm running Bash

One of the most commonly used shells in the Unix-like operating systems (i.e. macOS, GNU/Linux, BSD) is the Bash shell, in fact it is very often the default shell. To start a session you will often use a terminal emulator, which allow you to use a terminal session at the same time as other graphical applications. It doesn't really matter, which terminal emulator you use, generally you want one that has color and Unicode support. In macOS you can use Terminal.app which you can find under Applications > Utilities. A popular alternative is iTerm. On most Linux distributions you will usually be provided with at least one terminal emulator by default, otherwise you might want to try Terminator, Konsole, rxvt-unicode or something different.

When you open a new window or tab in your terminal emulator of choice you will be shown your prompt. What it looks like exactly depends a lot on configuration, which can vary greatly from OS to OS (you can configure everything to your likings, however this exceeds the scope of this short introduction). Generally it will indicate your current working directory, username and hostname. When working in the shell your session always has current working directory. Commands that accept relative filenames will use that directory as the base directory to look for files. By default you are in your user's home folder, which is often abbreviated with a tilde (~).

To execute a command you just type it into the shell and press enter.

At first we want to look at the command ls. If you type it in just like that it will print the files and directories in your current working directory. You can also provide a relative path to a directory you want to list, e.g. ls DIR. If you want more detailed information about the files you can use ls -l DIR, if you instead want to also include invisible entries (i.e. names starting with a dot) use ls -a. Of course it is possible to combine them both by running ls -l -a DIR or the short form ls -la DIR. Note that this kind of concatenating multiple arguments into one is only possible with single character parameters. Parameters can also come in long form, for example the equivalent of ls -a is ls --all DIR. Which forms are available depends on the individual command.

Now you might be thinking how to remember all parameters for every command you will ever use. Thankfully you only want to remember the most important ones, which are the ones you use most frequently, otherwise there is a nice way to look them up. You can either use the man command. For example run man ls to find more information about the ls command. Oftentimes you can find a more concise summary by trying to run the command in question followed by the parameter --help, however this is not something you can expect to work well with every command, whereas manual pages should be always available.

Back to the topic of current working directories. If you want to change your directory you can use cd followed by the directory you want to change to. There are two special virtual directories '.' and '..'. The single dot refers to the current directory while the double dot refers to a dir's parent directory. So executing cd .. changes into the parent directory of the current working directory.

A very brief summary of other useful commands:

cat FILE: display the contents of a file.

mkdir DIR: create a directory.


System-wide installation

A common and easy way to install Ruby is to perform a system-wide installation. Depending on the operating system installation procedures will be different (if required at all).

Windows logo - 2012

Windows

Windows Operating System did not have Ruby programing language pre-installed (unlike other platforms listed here) . To install Ruby programming language, it is highly recommended to install it from here: https://rubyinstaller.org/ .

Refer to right side bar: WHICH VERSION TO DOWNLOAD? for guide to download which version to download. Usually it will recommend the latest stable version to be downloaded.

You might see the options of Ruby+Devkit installer version as a selectable component. This option is important as to build native C/C++ extensions for Ruby and is necessary for Ruby on Rails. Moreover it allows the download and usage of hundreds of Open Source libraries which Ruby gems (packages) often depend on.

Download it and double click the file to be installed on the local PC.

Once install it, double click of Ruby Installer to start installing it on Windows

Step 1: Select "I accept the license" and click "Next" button

Step 2: Select the directory that you wanted to install to and below , select the "Add Ruby executables to your PATH" and "Associate .rb and .rbw files with the Ruby installation". Click "Next" buttons"

Step 3: Select all the checkboxes inside the setup files. Click "Next"

Step 4: Click "ridk install" and click "Next" button to proceed


Once finished installing, type cmd into Window search bar and type ruby -v sto see which version of ruby that are installed. If it is showing, congrats, you successfully installed Ruby language in the system.

MacOS logo (2017) macOS

Ruby comes preinstalled on macOS. To check which version is installed on your system, execute ruby -v inside a shell session.

If you want to install a more recent version of Ruby, you can:

  • Update to a newer version of macOS, which may have a more recent version of Ruby.
  • Use RVM or RBEnv tools specifically for managing multiple ruby versions (This is the most popular way because you can manage many Ruby versions and associate them with projects)
  • Use Fink, MacPorts, Homebrew general purpose packaging systems for mac.

Monochrome Tux Linux

On many Linux distributions Ruby is installed by default. To check if Ruby is installed on your system, run ruby -v in a shell session.

Where this is not the case, or you want to update the installed version, you should use your distribution's package manager. Here we will provide information for some popular Linux distributions here, however it is recommended to users of all distributions to familiarize themselves with their distribution's package manager, since this will allow for the most efficient software management. Whether this is a command-line or graphical application depends on the offerings of the distribution and personal preference of the user.

Debian / Ubuntu

The package manager Synaptic provides graphical package management. It is installed by default under Ubuntu and has to be installed manually on Debian (by running sudo apt-get install synaptic from the command line).

Instead of using Synaptic you can also use apt directly from the command-line (you can find further information in the Debian Wiki's article on Package Management). Execute sudo apt-get install ruby from the command line to install Ruby.

Fedora

From the command-line you can install Ruby with DNF by executing sudo dnf install ruby.

Arch Linux

Use pacman to install Ruby by executing pacman -S ruby as root.

Mandriva Linux

On Mandriva Linux, install Ruby using the command-line tool urpmi.

PCLinuxOS

On PCLinuxOS, install Ruby using either the graphical tool Synaptic or the command-line tool apt.

Red Hat Linux

On Red Hat Linux, install Ruby using the command-line tool RPM.

Per-user Installation

Per-user installations allow each user of the system to utilize their own particular version of Ruby without impact to other users.

Guix

To install the latest available version of Ruby, run: guix install ruby.

Setup Ruby in Windows

Ruby does not come preinstalled with any version of Microsoft Windows. However, there are several ways to install Ruby on Windows.

  • Download and install one of the compiled Ruby binaries from the Ruby web site.
  • Download and run the one click RubyInstaller.
  • Install Cygwin, a collection of free software tools available for Windows. During the install, make sure that you select the "ruby" package, located in the "Devel, Interpreters" category.

Setup Ruby in Windows with Notepad++

In latest version of Ruby and Window 10 , it is much more easier to setup Ruby now more than ever.

We will be using [1]Notepad++ Logo to start setup Ruby in Windows.

Once install Notepad++ in Windows, open up the programs and click on Plugins > Plugins Admin

At Plugins Admin , select Plugins , NppExec to install

Once installed, you can run NppExec by pressing F6

Building from Source

If your distro doesn't come with a ruby package or you want to build a specific version of ruby from scratch, please install it by following the directions here. Download from here.

Compile options

Building with debug symbols

If you want to install it with debug symbols built in (and are using gcc--so either Linux, cygwin, or mingw).

 ./configure --enable-shared optflags="-O0" debugflags="-g3 -ggdb"

Optimizations

Note that with 1.9 you can pass it --disable-install-doc to have it build faster.

To set the GC to not run as frequently (which tends to provide a faster experience for larger programs, like rdoc and rails), precede your build with

 $ export CCFLAGS=-DGC_MALLOC_LIMIT=80000000

though you might be able to alternately put those in as opt or debug flags, as well.

Testing Installation

The installation can be tested easily by executing:

$ ruby -v

This should produce an output similar to:

ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux]

If this shows up, then you have successfully installed Ruby. However if you get an error similar to:

-bash: ruby: command not found

then you did not successfully install Ruby.

Ruby editors

← Installing Ruby | Notation conventions →


What is Ruby IDE ?

Integrated development environment or IDE is a software tool generally contains at least a debugger, a source code editor, and build automation tools.

There are a few of text editor/IDE that can be used for Ruby Programming language (arranged alphabetically) as shown below :

Although you can write Ruby programs with any plain text editor, some text editors have additional features to aid the Ruby programmer. The most common is syntax highlighting.

P.S 1: For the ease of readers, the book will be dealing with Notepad++ as the more popular Ruby IDE, ATOMS will be sun-setted by GitHub in 15 Dec 2022.

P.S 2: Pulsar is fork from ATOM IDE. Listed below for conveniences.


Arcadia

Price: Iconoir no-coin (Free as in beer)

Website: https://www.arcadia-ide.org/

GNU Emacs

Price: Iconoir no-coin (Free as in beer)

Website: https://www.gnu.org/software/emacs/

ICEcoder

Price: Iconoir no-coin (Free as in beer)

Website: https://icecoder.net/

Komodo

Price: Iconoir no-coin (Free as in beer)

Website: https://www.activestate.com/products/komodo-ide/

Notepad++

Price: Iconoir no-coin (Free as in beer)

Website: https://notepad-plus-plus.org/

Pulsar

Price: Iconoir no-coin (Free as in beer)

Thumbs up font awesome Recommended for Freeware

Website: https://pulsar-edit.dev/

Ruby Packages: https://web.pulsar-edit.dev/packages/search?q=ruby

RubyMine

Price: Iconoir coinIconoir coinIconoir coin Iconoir coinIconoir coin (Annual subscription fee)

Thumbs up font awesome Recommended for Paidware

Website: https://www.jetbrains.com/ruby/whatsnew/

Sublime Text

Price: Iconoir coinIconoir coin (One off payment and receives 3 years of continuous updates)

Website: https://www.sublimetext.com/

Vim

Price: Iconoir no-coin (Free as in beer)

Website: https://www.vim.org/download.php#pc

References

Here is a link of spreadsheet of the various options available.

Notation conventions

← Ruby editors | Interactive Ruby →


Command-line examples

In this tutorial, examples that involve running programs on the command-line will use the dollar sign to denote the shell prompt. The part of the example that you type will appear bold. Since the dollar sign denotes your shell prompt, you should not type it in.

For example, to check what version of Ruby is on your system, run:

$ ruby -v

Again, do not type the dollar sign – you should only enter "ruby -v" (without the quotes). Windows users are probably more familiar seeing "C:\>" to denote the shell prompt (called the command prompt on Windows).

An example might also show the output of the program.

$ ruby -v
ruby 1.8.5 (2006-08-25) [i386-freebsd4.10]

In the above example, "ruby 1.8.5 (2006-08-25) [i386-freebsd4.10]" is printed out after you run "ruby -v". Your actual output when you run "ruby -v" will vary depending on the version of Ruby installed and what operating system you are using.

Running Ruby scripts

For simplicity, the following convention is used to show a Ruby script being run from the shell prompt.

$ hello-world.rb
Hello world

However, the actual syntax that you will use to run your Ruby scripts will vary depending on your operating system and how it is setup. Please read through the Executable Ruby scripts section of the Hello world page to determine the best way to run Ruby scripts on your system.

Running irb

Ruby typically installs with "interactive ruby" (irb) installed along with it. This is a REPL that allows you to experiment with Ruby, for example:

$ irb
>> 3 + 4
=> 7
>> 'abc'
=> "abc"

Interactive Ruby

← Notation conventions | Hello world →


When learning Ruby, you will often want to experiment with new features by writing short snippets of code. Instead of writing a lot of small text files, you can use irb, which is Ruby's interactive mode.

Running irb

Run irb from your shell prompt.

$ irb --simple-prompt
>>

The >> prompt indicates that irb is waiting for input. If you do not specify --simple-prompt, the irb prompt will be longer and include the line number. For example:

$ irb
irb(main):001:0>

A simple irb session might look like this.

$ irb --simple-prompt
>> 2+2
=> 4
>> 5*5*5
=> 125
>> exit

These examples show the user's input in bold. irb uses => to show you the return value of each line of code that you type in.

Cygwin users

If you use Cygwin's Bash shell on Microsoft Windows, but are running the native Windows version of Ruby instead of Cygwin's version of Ruby, read this section.

To run the native version of irb inside of Cygwin's Bash shell, run irb.bat.

By default, Cygwin's Bash shell runs inside of the Windows console, and the native Windows version of irb.bat should work fine. However, if you run a Cygwin shell inside of Cygwin's rxvt terminal emulator, then irb.bat will not run properly. You must either run your shell (and irb.bat) inside of the Windows console or install and run Cygwin's version of Ruby.

Understanding irb output

irb prints out the return value of each line that you enter. In contrast, an actual Ruby program only prints output when you call an output method such as puts.

For example:

$ irb --simple-prompt
>> x=3
=> 3
>> y=x*2
=> 6
>> z=y/6
=> 1
>> x
=> 3
>> exit

Helpfully, x=3 not only does an assignment, but also returns the value assigned to x, which irb then prints out. However, this equivalent Ruby program prints nothing out. The variables get set, but the values are never printed out.

x=3
y=x*2
z=y/6
x

If you want to print out the value of a variable in a Ruby program, use the puts method.

x=3
puts x

Mailing List FAQ

Etiquette

There is a list of Best Practices[1].


See some more questions answered.

  1. https://web.archive.org/web/20160327125758/http://blog.rubybestpractices.com/posts/jamesbritt/and_your_Mom_too.html

Basic Ruby - Hello world

← Interactive Ruby | Strings →

The classic Hello, world! program is a good way to get started with Ruby.

Hello, world!

Create a text file called hello_world.rb containing the following code:

puts 'Hello, world!'

Now run it at the shell prompt.

$ ruby hello_world.rb
Hello, world!

You can also run the short "Hello, world!" program without creating a text file at all. This is called a one-liner.

$ ruby -e "puts 'Hello, world!'"
Hello, world!

Option -e means evaluate (Ruby code). You can run this code with irb, but the output will look slightly different. puts will print out "Hello, world!", but irb will also print out the return value of puts — which is nil.

$ irb
>> puts "Hello, world!"
Hello, world!
=> nil

Comments

Like Perl, Bash, Python, and C Shell, Ruby uses the hash symbol (also called Pound Sign, number sign) for comments. Everything from the hash to the end of the line is ignored when the program is run by Ruby. For example, here's our hello_world.rb program with comments.

# My first Ruby program
# On my way to Ruby fame & fortune!
 
puts 'Hello, world!'

You can append a comment to the end of a line of code, as well. Everything before the hash is treated as normal Ruby code.

puts 'Hello, world!'  # Print out "Hello, world!"

You can also comment several lines at a time:

=begin
This program will
print "Hello, world!".
=end
 
puts 'Hello, world!'

Although block comments can start on the same line as =begin, the =end must have its own line. You cannot insert block comments in the middle of a line of code as you can in C, C++, and Java, although you can have non-comment code on the same line as the =end.

=begin This program will print 'Hello, world!'
=end puts 'Hello, world!'

Executable Ruby scripts

Typing the word ruby each time you run a Ruby script is tedious. To avoid doing this, follow the instructions below.

Unix-like operating systems

In Unix-like operating systems – such as Linux, Mac OS X, and Solaris you will want to mark your Ruby scripts as executable using the chmod command. This also works with the Cygwin version of Ruby.

$ chmod +x hello_world.rb

You need to do this each time you create a new Ruby script. If you rename a Ruby script, or edit an existing script, you do not need to run "chmod +x" again.

Next, add a shebang line as the very first line of your Ruby script. The shebang line is read by the shell to determine what program to use to run the script. This line cannot be preceded by any blank lines or any leading spaces. The new hello_world.rb program – with the shebang line – looks like this:

#!/usr/bin/ruby

puts 'Hello world'

If your ruby executable is not in the /usr/bin directory, change the shebang line to point to the correct path. The other common place to find the ruby executable is /usr/local/bin/ruby.

The shebang line is ignored by Ruby – since the line begins with a hash, Ruby treats the line as a comment. Hence, you can still run the Ruby script on operating systems such as Windows whose shell does not support shebang lines.

Now, you can run your Ruby script without typing in the word ruby. However, for security reasons, Unix-like operating systems do not search the current directory for executables unless it happens to be listed in your PATH environment variable. So you need to do one of the following:

  1. Create your Ruby scripts in a directory that is already in your PATH.
  2. Add the current directory to your PATH (not recommended).
  3. Specify the directory of your script each time you run it.

Most people start with #3. Running an executable Ruby script that is located in the current directory looks like this:

$ ./hello_world.rb

Once you have completed a script, it's common to create a ~/bin directory, add this to your PATH, and move your completed script here for running on a day-to-day basis. Then, you can run your script like this:

$ hello_world.rb

Using env

If you do not want to hard-code the path to the ruby executable, you can use the env command in the shebang line to search for the ruby executable in your PATH and execute it. This way, you will not need to change the shebang line on all of your Ruby scripts if you move them to a computer with Ruby installed in a different directory.

#!/usr/bin/env ruby

puts 'Hello world'

Windows

If you install the native Windows version of Ruby using the Ruby One-Click Installer, then the installer has setup Windows to automatically recognize your Ruby scripts as executables. Just type the name of the script to run it.

$ hello_world.rb
Hello world

If this does not work, or if you installed Ruby in some other way, follow these steps.

  1. Log in as an administrator.
  2. Run the standard Windows "Command Prompt", cmd.
  3. At the command prompt (i.e. shell prompt), run the following Windows commands. When you run ftype, change the command-line arguments to correctly point to where you installed the ruby.exe executable on your computer.
$ assoc .rb=RubyScript
.rb=RubyScript

$ ftype RubyScript="c:\ruby\bin\ruby.exe" "%1" %*
RubyScript="c:\ruby\bin\ruby.exe" "%1" %*

For more help with these commands, run "help assoc" and "help ftype".

Basic Ruby - Strings

← Hello world | Alternate quotes →


Like Python, Java, and the .NET Framework, Ruby has a built-in String class.

String literals

One way to create a String is to use single or double quotes inside a Ruby program to create what is called a string literal. We've already done this with our "hello world" program. A quick update to our code shows the use of both single and double quotes.

puts 'Hello world'
puts "Hello world"

Being able to use either single or double quotes is similar to Perl, but different from languages such as C and Java, which use double quotes for string literals and single quotes for single characters.

So what difference is there between single quotes and double quotes in Ruby? In the above code, there's no difference. However, consider the following code:

puts "Betty's pie shop"
puts 'Betty\'s pie shop'

Because "Betty's" contains an apostrophe, which is the same character as the single quote, in the second line we need to use a backslash to escape the apostrophe so that Ruby understands that the apostrophe is in the string literal instead of marking the end of the string literal. The backslash followed by the single quote is called an escape sequence.

Single quotes

Single quotes only support two escape sequences.

  • \' – single quote
  • \\ – single backslash

Except for these two escape sequences, everything else between single quotes is treated literally.

Double quotes

Double quotes allow for many more escape sequences than single quotes. They also allow you to embed variables or Ruby code inside of a string literal – this is commonly referred to as interpolation.

puts "Enter name"
name = gets.chomp
puts "Your name is #{name}"

Escape sequences

Below are some of the more common escape sequences that can appear inside of double quotes.

Try out this example code to better understand escape sequences.

puts "Hello\t\tworld"
 
puts "Hello\b\b\b\b\bGoodbye world"
 
puts "Hello\rStart over world"
 
puts "1. Hello\n2. World"

The result:

$ double-quotes.rb
Hello		world
Goodbye world
Start over world
1. Hello
2. World

Notice that the newline escape sequence (in the last line of code) simply starts a new line.

The bell character, produced by escape code \a, is considered a control character. It does not represent a letter of the alphabet, a punctuation mark, or any other written symbol. Instead, it instructs the terminal emulator (called a console on Microsoft Windows) to "alert" the user. It is up to the terminal emulator to determine the specifics of how to respond, although a beep is fairly standard. Some terminal emulators will flash briefly.

Run the following Ruby code to check out how your terminal emulator handles the bell character.

puts "\aHello world\a"

puts

We've been using the puts function quite a bit to print out text. Whenever puts prints out text, it automatically prints out a newline after the text. For example, try the following code.

puts "Say", "hello", "to", "the", "world"

The result:

$ hello-world.rb
Say
hello
to
the
world

print

In contrast, Ruby's print function only prints out a newline if you specify one. For example, try out the following code. We include a newline at the end of print's argument list so that the shell prompt appears on a new line, after the text.

 print "Say", "hello", "to", "the", "world", "\n"

The result:

$ hello-world.rb
Sayhellototheworld

The following code produces the same output, with all the words run together.

print "Say"
print "hello"
print "to"
print "the"
print "world"
print "\n"

See also

String literals

Basic Ruby - Alternate quotes

← Strings | Here documents →


In Ruby, there's more than one way to quote a string literal. Much of this will look familiar to Perl programmers.

These alternative methods are:

  • single quotes with the %q operator: %q(abc) is the same as 'abc'
  • double quotes with the %Q operator: %Q(abc's) is the same as "abc's"

Alternate single quotes

Let's say we are using single quotes to print out the following path.

puts 'c:\bus schedules\napolean\the portland bus schedule.txt'

This will result in the following output:

c:\bus schedules\napolean\the portland bus schedule.txt

The single quotes keep the \b, \n, and \t from being treated as escape sequences (the same cannot be said for wikibooks' syntax highlighting).

Now let's consider the following string literal:

puts 'c:\napolean\'s bus schedules\tomorrow\'s bus schedule.txt'

This outputs:

c:\napolean's bus schedules\tomorrow's bus schedule.txt

Escaping the apostrophes makes the code less readable and makes it less obvious what will print out.

Luckily, in Ruby, there's a better way. You can use the %q operator to apply single-quoting rules, and choose your own delimiter. This delimiter will mark the beginning and end of the string literal.

puts %q!c:\napolean's documents\tomorrow's bus schedule.txt!
puts %q/c:\napolean's documents\tomorrow's bus schedule.txt/
puts %q^c:\napolean's documents\tomorrow's bus schedule.txt^
puts %q(c:\napolean's documents\tomorrow's bus schedule.txt)
puts %q{c:\napolean's documents\tomorrow's bus schedule.txt}
puts %q<c:\napolean's documents\tomorrow's bus schedule.txt>

Each line will print out the same text:

c:\napolean's documents\tomorrow's bus schedule.txt

You can use any punctuation you want as a delimiter, not just the ones listed in the example.

Of course, if your chosen delimiter appears inside of the string literal, then you need to escape it.

puts %q#c:\napolean's documents\tomorrow's \#9 bus schedule.txt#

If you use matching braces to delimit the text, however, you can nest braces, without escaping them.

puts %q(c:\napolean's documents\the (bus) schedule.txt)
puts %q{c:\napolean's documents\the {bus} schedule.txt}
puts %q<c:\napolean's documents\the <bus> schedule.txt>

Alternate double quotes

The %Q operator (notice the case of Q in %Q) allows you to create a string literal using double-quoting rules, but without using the double quote as a delimiter. It works much the same as the %q operator.

 print %Q^Say:\tHello world\n\tHello world\n^
 print %Q(Say:\tHello world\n\tHello world\n)

Just like double quotes, you can interpolate Ruby code inside of these string literals.

 name = 'Charlie Brown'
 
 puts %Q!Say "Hello," #{name}.!
 puts %Q/What is "4 plus 5"? Answer: #{4+5}/

Basic Ruby - Here documents

← Alternate quotes | ASCII →


For creating multiple-line strings, Ruby supports here documents (heredocs), a feature that originated in the Bourne shell and is also available in Perl and PHP.

Here documents

To construct a here document, the << operator is followed by an identifier that marks the end of the here document. The end mark is called the terminator. The lines of text prior to the terminator are joined together, including the newlines and any other whitespace.

puts <<GROCERY_LIST
Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*

* Organic
GROCERY_LIST

The result:

Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*

* Organic

If we pass the puts function multiple arguments, the string literal created from the here document is inserted into the argument list wherever the << operator appears.

In the code below, the here-document (containing the four grocery items and a blank line) is passed in as the third argument. We get the same output as above.

puts 'Grocery list', '------------', <<GROCERY_LIST, '* Organic'
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*

GROCERY_LIST

Multiple here documents

You can also have multiple here documents in an argument list. We added a blank line at the end of each here document to make the output more readable.

puts 'Produce', '-------', <<PRODUCE, 'Dairy', '-----', <<DAIRY, '* Organic'
1. Strawberries*
2. Blueberries

PRODUCE
1. Yogurt
2. Milk*
3. Cottage Cheese

DAIRY

The output after running this code is:

Produce
-------
1. Strawberries*
2. Blueberries

Dairy
-----
1. Yogurt
2. Milk*
3. Cottage Cheese

* Organic

We have been using the puts function in our examples, but you can pass here documents to any function that accepts Strings.

Indenting

If you indent the lines inside the here document, the leading whitespace is preserved. However, there must not be any leading whitespace before the terminator.

puts 'Grocery list', '------------', <<Grocery_list
    1. Salad mix.
    2. Strawberries.
    3. Cereal.
    4. Milk.
Grocery_list

The result:

Grocery list
------------
    1. Salad mix.
    2. Strawberries.
    3. Cereal.
    4. Milk.

Indenting the terminator

If, for readability, you want to also indent the terminator, use the <<- operator.

puts 'Grocery list', '------------', <<-GROCERY_LIST
    1. Salad mix.
    2. Strawberries.
    3. Cereal.
    4. Milk.
    GROCERY_LIST

Note, however, that the whitespace before each line of text within the here document is still preserved.

Grocery list
------------
    1. Salad mix.
    2. Strawberries.
    3. Cereal.
    4. Milk.

Quoting rules

You may wonder whether here documents follow single-quoting or double-quoting rules.

Double-quoting rules

If there are no quotes around the identifier, like in our examples so far, then the body of the here document follows double-quoting rules.

name = 'Charlie Brown'

puts <<QUIZ
Student: #{name}
 
1.\tQuestion: What is 4+5?
\tAnswer: The sum of 4 and 5 is #{4+5}
QUIZ

The output of this example is:

Student: Charlie Brown
 
1.&#09;Question: What is 4+5?
&#09;Answer: The sum of 4 and 5 is 9

Double-quoting rules are also followed if you put double quotes around the identifier. However, do not put double quotes around the terminator.

puts <<"QUIZ"
Student: #{name}

1.\tQuestion: What is 4+5?
\tAnswer: The sum of 4 and 5 is #{4+5}
QUIZ

Single-quoting rules

To create a here document that follows single-quoting rules, place single quotes around the identifier.

puts <<'BUS_SCHEDULES'
c:\napolean's documents\tomorrow's bus schedule.txt
c:\new documents\sam spade's bus schedule.txt
c:\bus schedules\the #9 bus schedule.txt
BUS_SCHEDULES

The result:

c:\napolean's documents\tomorrow's bus schedule.txt
c:\new documents\sam spade's bus schedule.txt
c:\bus schedules\the #9 bus schedule.txt

Basic Ruby - Introduction to objects

← Encoding | Ruby basics →


Like Smalltalk, Ruby is a pure object-oriented language — everything is an object. In contrast, languages such as C++ and Java are hybrid languages that divide the world between objects and primitive types. The hybrid approach results in better performance for some applications, but the pure object-oriented approach is more consistent and simpler to use.

What is an object?

Using Smalltalk terminology, an object can do exactly three things.

  1. Hold state, including references to other objects.
  2. Receive a message, from both itself and other objects.
  3. In the course of processing a message, send messages, both to itself and to other objects.

If you don't come from Smalltalk background, it might make more sense to rephrase these rules as follows:

  1. An object can contain data, including references to other objects.
  2. An object can contain methods, which are functions that have special access to the object's data.
  3. An object's methods can call/run other methods/functions.

Variables and objects

Let's fire up irb to get a better understanding of objects.

$ irb --simple-prompt
>> comedian = "Stephen Colbert"
=> "Stephen Colbert"

In the first line, we created a String object containing the text "Stephen Colbert". We also told Ruby to use the variable comedian to refer to this object.

Next, we tell Ruby to also use the variable favorite_comedian to refer to the same String object.

>> favorite_comedian = comedian
=> "Stephen Colbert"

Now, we have two variables that we can use to refer to the same String object — comedian and favorite_comedian. Since they both refer to the same object, if the object changes (as we'll see below), the change will show up when using either variable.

Methods

In Ruby, methods that end with an exclamation mark (also called a "bang") modify the object. For example, the method upcase! changes the letters of a String to uppercase.

>> comedian.upcase!
=> "STEPHEN COLBERT"

Since both of the variables comedian and favorite_comedian point to the same String object, we can see the new, uppercase text using either variable.

>> comedian
=> "STEPHEN COLBERT"
>> favorite_comedian
=> "STEPHEN COLBERT"

Methods that do not end in an exclamation point return data, but do not modify the object. For example, downcase! modifies a String object by making all of the letters lowercase. However, downcase returns a lowercase copy of the String, but the original string remains the same.

>> comedian.downcase
=> "stephen colbert"
>> comedian
=> "STEPHEN COLBERT"

Since the original object still contains the text "STEPHEN COLBERT", you might wonder where the new String object, with the lowercase text, went to. Well, after irb printed out its contents, it can no longer be accessed since we did not assign a variable to keep track of it. It's essentially gone, and Ruby will dispose of it.

Reassigning a variable

But what if your favorite comedian is not Stephen Colbert? Let's point favorite_comedian to a new object.

>> favorite_comedian = "Jon Stewart"
=> "Jon Stewart"

Now, each variable points to a different object.

Let's say that we change our mind again. Now, our favorite comedian is Ellen DeGeneres.

>> favorite_comedian = "Ellen DeGeneres"
=> "Ellen DeGeneres"

Now, no variable points to the "Jon Stewart" String object any longer. Hence, Ruby will dispose of it.

Basic Ruby - Ruby basics

← Introduction to objects | Data types →


As with the rest of this tutorial, we assume some basic familiarity with programming language concepts (i.e. if statement, while loops) and also some basic understanding of object-oriented programming.

Dealing with variables

We'll deal with variables in much more depth when we talk about classes and objects. For now, let's just say your basic local variable names should start with either a lower case letter or an underscore, and should contain upper or lower case letters, numbers, and underscore characters. Global variables start with a $.

Program flow

Ruby includes a pretty standard set of looping and branching constructs: if, while and case

For example, here's if in action:

a = 10 * rand

if a < 5
  puts "#{a} less than 5"
elsif a > 7
  puts "#{a} greater than 7"
else
  puts "Cheese sandwich!"
end

[As in other languages, the rand function generates a random number between 0 and 1]

There will be plenty more time to discuss conditional statements in later chapters. The above example should be pretty clear.

Ruby also includes a negated form of if called unless which goes something like

unless a > 5
  puts "a is less than or equal to 5"
else
  puts "a is greater than 5"
end

Generally speaking, Ruby keeps an if statement straight as long as the conditional (if ...) and the associated code block are on separate lines. If you have to smash everything together on one line, you'll need to place the then keyword after the conditional

if a < 5 then puts "#{a} less than 5" end 
if a < 5 then puts "#{a} less than 5" else puts "#{a} greater than 5" end

Note that the if statement is also an expression; its value is the last line of the block executed. Therefore, the line above could also have been written as

puts(if a < 5 then "#{a} less than 5" else "#{a} greater than 5" end)

Ruby has also adopted the syntax from Perl where if and unless statements can be used as conditional modifiers after a statement. For example

puts "#{a} less than 5" if a < 5
puts "Cheese sandwich" unless a == 4

while behaves as it does in other languages -- the code block that follows is run zero or more times, as long as the conditional is true

while a > 5
  a = 10*rand
end

And like if, there is also a negated version of while called until which runs the code block until the condition is true.

Finally there is the case statement which we'll just include here with a brief example. case is actually a very powerful super version of the if ... elsif... system

a = rand(11) # Outputs a random integer between 0 and 10

case a
when 0..5
  puts "#{a}: Low"
when 6
  puts "#{a}: Six"
else
  puts "#{a}: Cheese toast!"
end

There are some other interesting things going on in this example, but here the case statement is the center of attention.

Writing functions

In keeping with Ruby's all-object-oriented-all-the-time design, functions are typically referred to as methods. No difference. We'll cover methods in much more detail when we get to objects and classes. For now, basic method writing looks something like this (save the following code in a file called func1.rb):

# Demonstrate a method with func1.rb
def my_function( a )
  puts "Hello, #{a}"
  return a.length
end

len = my_function( "Giraffe" )
puts "My secret word is #{len} characters long"

now run the script:

$ func1.rb
Hello, Giraffe
My secret word is 7 characters long

Methods are defined with the def keyword, followed by the function name. As with variables, local and class methods should start with a lower case letter.

In this example, the function takes one argument (a) and returns a value. Note that the input arguments aren't typed (i.e. a need not be a string) ... this allows for great flexibility but can also cause a lot of trouble. The function also returns a single value with the return keyword. Technically this isn't necessary -- the value of the last line executed in the function is used as the return value -- but more often than not using return explicitly makes things clearer.

As with other languages, Ruby supports both default values for arguments and variable-length argument lists, both of which will be covered in due time. There's also support for code blocks, as discussed below.

Blocks

One very important concept in Ruby is the code block. It's actually not a particularly revolutionary concept -- any time you've written if ... { ... } in C or Perl you've defined a code block, but in Ruby a code block has some hidden secret powers...

Code blocks in Ruby are defined either with the keywords do..end or the curly brackets {..}

do
  print "I like "
  print "code blocks!"
end

{
  print "Me too!"
}

One very powerful usage of code blocks is that methods can take one as a parameter and execute it along the way.

[ed note: the Pragmatic Programmers actually want to point out that it's not very useful to describe it this way. Instead, the block of code behaves like a 'partner' to which the function occasionally hands over control]

The concept can be hard to get the first time it's explained to you. Here's an example:

$ irb --simple-prompt
>> 3.times { puts "Hi!" }
Hi!
Hi!
Hi!
=> 3

Surprise! You always thought 3 was just a number, but it's actually an object (of type Fixnum) As it's an object, it has a member function times which takes a block as a parameter. The function runs the block 3 times.

Blocks can actually receive parameters, using a special notation |..|. In this case, a quick check of the documentation for times shows it will pass a single parameter into the block, indicating which loop it's on:

$ irb --simple-prompt
>> 4.times { |x| puts "Loop number #{x}" }
Loop number 0
Loop number 1
Loop number 2
Loop number 3
=> 4

The times function passes a number into the block. The block gets that number in the variable x (as set by the |x|), then prints out the result.

Functions interact with blocks through the yield. Every time the function invokes yield control passes to the block. It only comes back to the function when the block finishes. Here's a simple example:

# Script block2.rb

def simpleFunction
  yield 
  yield
end

simpleFunction { puts "Hello!" }
$ block2.rb
Hello!
Hello!

The simpleFunction simply yields to the block twice -- so the block is run twice and we get two times the output. Here's an example where the function passes a parameter to the block:

# Script block1.rb

def animals
  yield "Tiger"
  yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }
$ block1.rb
Hello, Tiger
Hello, Giraffe

It might take a couple of reads through to figure out what's going on here. We've defined the function "animals" -- it expects a code block. When executed, the function calls the code block twice, first with the parameter "Tiger" then again with the parameter "Giraffe". In this example, we've written a simple code block which just prints out a greeting to the animals. We could write a different block, for example:

animals { |x| puts "It's #{x.length} characters long!" }

which would give:

It's 5 characters long!
It's 7 characters long!

Two completely different results from running the same function with two different blocks.

There are many powerful uses of blocks. One of the first you'll come across is the each function for arrays -- it runs a code block once for each element in the array -- it's great for iterating over lists.

Ruby is really, really object-oriented

Ruby is very object oriented. Everything is an object -- even things you might consider constants. This also means that the vast majority of what you might consider "standard functions" aren't floating around in some library somewhere, but are instead methods of a given variable.

Here's one example we've already seen:

3.times { puts "Hi!" }

Even though 3 might seem like just a constant number, it's in fact an instance of the class Fixnum (which inherits from the class Numeric which inherits from the class Object). The method times comes from Fixnum and does just what it claims to do.

Here are some other examples

$ irb --simple-prompt
>> 3.abs
=> 3
>> -3.abs
=> 3
>> "giraffe".length
=> 7
>> a = "giraffe"
=> "giraffe"
>> a.reverse
=> "effarig"

There will be lots of time to consider how object-oriented design filters through Ruby in the coming chapters.

Basic Ruby - Data types

← Ruby basics | Writing methods →


Ruby Data Types

As mentioned in the previous chapter, everything in Ruby is an object. Ruby has 8 primary data types and 3 more data types derived from the Numeric superclass. Everything has a class. Don't believe me? Try running this bit of code:

h = {"hash?" => "yep, it\'s a hash!", "the answer to everything" => 42, :linux => "fun for coders."}
puts "Stringy string McString!".class
puts 1.class
puts 1.class.superclass
puts 1.class.superclass.superclass
puts 4.3.class
puts 4.3.class.superclass
puts nil.class
puts h.class
puts :symbol.class
puts [].class
puts (1..8).class

displays

String
Fixnum
Integer
Numeric
Float
Numeric
NilClass
Hash
Symbol
Array
Range


See? Everything is an object. Every object has a method called class that returns that object's class. You can call methods on pretty much anything. Earlier you saw an example of this in the form of 3.times. (Technically when you call a method you're sending a message to the object, but I'll leave the significance of that for later.)
Something that makes this extreme object oriented-ness very fun for me is the fact that all classes are open, meaning you can add variables and methods to a class at any time during the execution of your code. This, however, is a discussion of datatypes.

Constants

We'll start off with constants because they're simple. Two things to remember about constants:
1. Constants start with capital letters. Constant is a constant. constant is not a constant.
2. You can change the values of constants, but Ruby will give you a warning. (Silly, I know... but what can you do?)
Congrats. Now you're an expert on Ruby constants.

Symbols

So did you notice something weird about that first code listing? "What the heck was that colon thingy about?" Well, it just so happens that Ruby's object oriented ways have a cost: lots of objects make for slow code. Every time you type a string, Ruby makes a new object. Regardless of whether two strings are identical, Ruby treats every instance as a new object. You could have "live long and prosper" in your code once and then again later on and Ruby wouldn't even realize that they're pretty much the same thing. Here is a sample irb session which demonstrates this fact:

irb> "live long and prosper".object_id
=> -507772268
irb> "live long and prosper".object_id
=> -507776538

Notice that the object ID returned by irb Ruby is different even for the same two strings.

To get around this memory hoggishness, Ruby has provided "symbols." Symbols are lightweight objects best used for comparisons and internal logic. If the user doesn't ever see it, why not use a symbol rather than a string? Your code will thank you for it. Let us try running the above code using symbols instead of strings:

irb> :my_symbol.object_id
=> 150808
irb> :my_symbol.object_id
=> 150808

Symbols are denoted by the colon sitting out in front of them, like so: :symbol_name

Hashes

Hashes are like dictionaries, in a sense. You have a key, a reference, and you look it up to find the associated object, the definition.

The best way to illustrate this, I think, is with a quick demonstration:

hash = { :leia => "Princess from Alderaan", :han => "Rebel without a cause", :luke => "Farmboy turned Jedi"}
puts hash[:leia]
puts hash[:han]
puts hash[:luke]

displays

Princess from Alderaan
Rebel without a cause
Farmboy turned Jedi

I could have also written this like so:

hash = { :leia => "Princess from Alderaan", :han => "Rebel without a cause", :luke => "Farmboy turned Jedi"}
hash.each do |key, value|
     puts value
end

This code cycles through each element in the hash, putting the key in the key variable and the value in the value variable, which is then displayed

Princess of Alderaan
Rebel without a cause
Farmboy turned Jedi

I could have been more verbose about defining my hash; I could have written it like this:

hash = Hash.[](:leia => "Princess from Alderaan", :han => "Rebel without a cause", :luke => "Farmboy turned Jedi")
hash.each do |key, value|
     puts value
end

If I felt like offing Luke, I could do something like this:

hash.delete(:luke)

Now Luke's no longer in the hash. Or lets say I just had a vendetta against farmboys in general. I could do this:

hash.delete_if {|key, value| value.downcase.match("farmboy")}

This iterates through each key-value pair and deletes it, but only if the block of code following it returns true. In the block I made the value lowercase (in case the farmboys decided to start doing stuff like "FaRmBoY!1!") and then checked to see if "farmboy" matched anything in its contents. I could have used a regular expression, but that's another story entirely.

I could add Lando into the mix by assigning a new value to the hash:

hash[:lando] = "Dashing and debonair city administrator."

I can measure the hash with hash.length. I can look at only keys with the hash.keys method, which returns the hash's keys as an Array. Speaking of which...

Arrays

Arrays are a lot like Hashes, except that the keys are always consecutive numbers, and always starts at 0. In an Array with five items, the last element would be found at array[4] and the first element would be found at array[0]. In addition, all the methods that you just learned with Hashes can also be applied to Arrays.

Here are two ways to create an Array:

array1 = ["hello", "this", "is", "an", "array!"]
array2 = []
array2 << "This"   # index 0
array2 << "is"     # index 1
array2 << "also"   # index 2
array2 << "an"     # index 3
array2 << "array!" # index 4

As you may have guessed, the << operator pushes values onto the end of an Array. If I were to write puts array2[4] after declaring those two Arrays the output would be array!. Of course, if I felt like simultaneously getting array! and deleting it from the array, I could just Array.pop it off. The Array.pop method returns the last element in an array and then immediately removes it from that array:

string = array2.pop

Then string would hold array! and array2 would be an element shorter.
If I kept doing this, array2 wouldn't hold any elements. I can check for this condition by calling the Array.empty? method. For example, the following bit of code moves all the elements from one Array to another:

array1 << array2.pop until array2.empty?

Here's something that really excites me: Arrays can be subtracted from, and added to, each other. I can't vouch for every language that's out there, but I know that Java, C++, C# and perl would all look at me like I was a crazy person if I tried to execute the following bit of code:

array3 = array1 - array2
array4 = array1 + array2

After that code is evaluated, all of the following are true:

  • array3 contains all of the elements that array1 did, except the ones that were also in array2.
  • All the elements of array1, minus the elements of array2, are now contained within array3.
  • array4 now contains all the elements of both array1 and array2.

You may search for a particular value in variable array1 with the Array.include? method: array1.include?("Is this in here?")

If you just wanted to turn the whole Array into a String, you could:

string = array2.join(" ")

If array2 had the value that we declared in the last example, then string's value would be

This is also an array!

We could have called the Array.join method without any arguments:

string = array2.join

string's value would now be

Thisisalsoanarray!

Strings

I would recommend reading the chapters on strings and alternate quotes now if you haven't already. This chapter is going to cover some pretty spiffy things with Strings and just assume that you already know the information in these two chapters.

In Ruby, there are some pretty cool built-in functions where Strings are concerned. For example, you can multiply them:

"Danger, Will Robinson!" * 5

yields

Danger, Will Robinson!Danger, Will Robinson!Danger, Will Robinson!Danger, Will Robinson!Danger, Will Robinson!

Strings may also be compared:

"a" < "b"

yields

true

The preceding evaluation is actually comparing the ASCII values of the characters. But what, I hear you ask, is the ASCII value of an given character? With ruby versions prior to 1.9 you can find the ASCII value of a character with:

puts ?A

However, With Ruby version 1.9 or later that no longer works. Instead, you can try the String.ord method:

puts "A".ord

Either approach will display

65

which is the ASCII value of A. Simply replace A with whichever character you wish to inquire about.

To perform the opposite conversion (from 65 to A, for instance), use the Integer.chr method:

puts 65.chr

displays

A

Concatenation works the same as most other languages: putting a + character between two Strings will yield a new String whose value is the same as the others, one after another:

"Hi, this is " + "a concatenated string!"

yields

Hi, this is a concatenated string!

For handling pesky String variables without using the concatenate operator, you can use interpolation. In the following chunk of code string1, string2, and string3 are identical:

thing1 = "Red fish, "
thing2 = "blue fish."
string1 = thing1 + thing2 + " And so on and so forth."
string2 = "#{thing1 + thing2} And so on and so forth."
string3 = "#{thing1}#{thing2} And so on and so forth."

If you need to iterate through (that is, step through each of) the letters in a String object, you can use the String.scan method:

thing = "Red fish"
thing.scan(/./) {|letter| puts letter}

Displays each letter in thing (puts automatically adds a newline after each call):

R
e
d
 
f
i
s
h

But what's with that weird "/./" thing in the parameter? That, my friend, is called a regular expression. They're helpful little buggers, quite powerful, but outside the scope of this discussion. All you need to know for now is that /./ is "regex" speak for "any one character." If we had used /../ then ruby would have iterated over each group of two characters, and missed the last one since there's an odd number of characters!

Another use for regular expressions can be found with the =~ operator. You can check to see if a String matches a regular expression using the match operator, =~:

puts "Yeah, there's a number in this one." if "C3-P0, human-cyborg relations" =~ /[0-9]/

displays

Yeah, there's a number in this one.

The String.match method works much the same way, except it can accept a String as a parameter as well. This is helpful if you're getting regular expressions from a source outside the code. Here's what it looks like in action:

puts "Yep, they mentioned Jabba in this one." if "Jabba the Hutt".match("Jabba")

Alright, that's enough about regular expressions. Even though you can use regular expressions with the next two examples, we'll just use regular old Strings. Lets pretend you work at the Ministry of Truth and you need to replace a word in a String with another word. You can try something like:

string1 = "2 + 2 = 4"
string2 = string1.sub("4", "5")

Now string2 contains 2 + 2 = 5. But what if the String contains lots of lies like the one you just corrected? String.sub only replaces the first occurrence of a word! I guess you could iterate through the String using String.match method and a while loop, but there's a much more efficient way to accomplish this:

winston = %q{   Down with Big Brother!
		Down with Big Brother!
		Down with Big Brother!
		Down with Big Brother!
		Down with Big Brother!}
winston.gsub("Down with", "Long live")

Big Brother would be so proud! String.gsub is the "global substitute" function. Every occurrence of "Down with" has now been replaced with "Long live" so now winston is only proclaiming its love for Big Brother, not its disdain thereof.
On that happy note, lets move on to Integers and Floats. If you want to learn more about methods in the String class, look at the end of this chapter for a quick reference table.

Numbers (Integers and Floats)

You can skip this paragraph if you know all the standard number operators. For those who don't, here's a crash course. + adds two numbers together. - subtracts them. / divides. * multiplies. % returns the remainder of two divided numbers.

Alright, integers are numbers with no decimal place. Floats are numbers with decimal places. 10 / 3 yields 3 because dividing two integers yields an integer. Since integers have no decimal places all you get is 3. If you tried 10.0 / 3 you would get 3.33333... If you have even one float in the mix you get a float back. Capisce?

Alright, let's get down to the fun part. Everything in Ruby is an object, let me reiterate. That means that pretty much everything has at least one method. Integers and floats are no exception. First I'll show you some integer methods.
Here we have the venerable times method. Use it whenever you want to do something more than once. Examples:

puts "I will now count to 99..."
100.times {|number| puts number}
5.times {puts "Guess what?"}
puts "I'm done!"

This will print out the numbers 0 through 99, print out Guess what? five times, then say I'm done! It's basically a simplified for loop. It's a little slower than a for loop by a few hundredths of a second or so; keep that in mind if you're ever writing Ruby code for NASA. ;-)

Alright, we're nearly done, six more methods to go. Here are three of them:

# First a visit from The Count...
1.upto(10) {|number| puts "#{number} Ruby loops, ah-ah-ah!"}

# Then a quick stop at NASA...
puts "T-minus..."
10.downto(1) {|x| puts x}
puts "Blast-off!"

# Finally we'll settle down with an obscure Schoolhouse Rock video...
5.step(50, 5) {|x| puts x}

Alright, that should make sense. In case it didn't, upto counts up from the number it's called from to the number passed in its parameter. downto does the same, except it counts down instead of up. Finally, step counts from the number its called from to the first number in its parameters by the second number in its parameters. So 5.step(25, 5) {|x| puts x} would output every multiple of five starting with five and ending at twenty-five.

Time for the last three:

string1 = 451.to_s
string2 = 98.6.to_s
int = 4.5.to_i
float = 5.to_f

to_s converts floats and integers to strings. to_i converts floats to integers. to_f converts integers to floats. There you have it. All the data types of Ruby in a nutshell. Now here's that quick reference table for string methods I promised you.

Additional String Methods

# Outputs 1585761545
"Mary J".hash

# Outputs "concatenate"
"concat" + "enate"

# Outputs "Washington"
"washington".capitalize

# Outputs "uppercase"
"UPPERCASE".downcase

# Outputs "LOWERCASE"
"lowercase".upcase

# Outputs "Henry VII"
"Henry VIII".chop

# Outputs "rorriM"
"Mirror".reverse

# Outputs 810
"All Fears".sum

# Outputs cRaZyWaTeRs
"CrAzYwAtErS".swapcase

# Outputs "Nexu" (next advances the word up one value, as if it were a number.)
"Next".next

# After this, nxt == "Neyn" (to help you understand the trippiness of next)
nxt = "Next"
20.times {nxt = nxt.next}

Basic Ruby - Writing methods

← Data types | Classes and objects →


Method definition

A method definition is started with the def keyword and ended with the end keyword. Some programmers find the method definition notation in Ruby very similar to the one of Python.

def myMethod
end

To define a method that takes a parameter, you can put the name of the variable in parantheses after the method name. When the method is invoked, the code in the method will be run with a local variable with the name of the specified parameter.

def myMethod(msg)
  puts msg
end

If you need multiple parameters you can separate them with a comma.

def myMethod(msg, person)
  puts "Hi, my name is " + person + ". Some information about myself: " + msg
end

Invoking methods

You can invoke methods with or without parentheses although it can be considered bad style if you omit them, so the safe way is to always write them in the beginning until you know when it's safe to leave them away.

# With parentheses
myMethod()

# Without parentheses
myMethod

If you want to invoke a method with parameters you need to put the parameter(s) between the brackets (or if you omit them, between the invisible brackets) and separate them with commas if there are more than one.

def myMethod(a, b)
  puts a + b
end

myMethod(1, 2)
myMethod 1, 2
myMethod("abc", "xyz")

You can also use the value of a variable as a parameter.

def myMethod(a)
  puts "Hello " + a
end

name = "World"
myMethod(name)

Default values

Often, a method may have parameters of which many, if not all, could have clever defaults. Having to specify all of the parameters every time you invoke the method can be an inconvenience. Because of this, it's possible to define default values. This can be actually quite easily; simply assign the parameter a value in the definition. You can combine parameters with and without default values.

def myMethod(message="This is a default value")
  puts message
end

myMethod()
myMethod("Where has the default value gone?")

Returning values

You often want a method to return a value. You can do so by using the return statement.

def myMethod
  return "Hello"
end

puts myMethod()

However, because Ruby developers are lazy, they developed a feature that always returns the last evaluated statement (sometimes it's a bit tricky to know which one this is). Knowing this, you can turn the above example into the following:

def myMethod
  "Hello"
end

puts myMethod()

Note that a return statement finishes the execution of a method. Combined with the fact that you can return without a value this is often useful to stop a method from further execution if certain conditions are met.

def myMethod
  while true
    puts "Because the condition of this while loop is 'true' it will run forever, right?"
    return
  end
end

See also

This page was only meant to give some introduction how to work with methods in Ruby because this is a very important concept. However there is a more detailed page about methods and some other cool things that weren't mentioned here.

Basic Ruby - Classes and objects

← Writing methods | Exceptions →


Ruby Classes

As stated before, everything in Ruby is an object. Every object has a class. To find the class of an object, simply call that object's class method. For example, try this:

    puts "This is a string".class
    puts 9.class
    puts ["this","is","an","array"].class
    puts ({:this => "is", :a => "hash"}).class
    puts :symbol.class

Anyhow, you should already know this. What you don't know however, is how to make your own classes and extend Ruby's classes.

Creating Instances of a Class

An instance of a class is an object that belongs to that class. For example, "chocolate" is an instance of the String class. You already know that you can create strings, arrays, hashes, numbers, and other built-in types by simply using quotes, brackets, curly braces, etc., but you can also create them via the new method. For example, my_string = "" is the same as my_string = String.new. Almost every class has a new method: arrays, hashes, whatever. (Some classes like Integers and Numerics do not have the new method. These classes do not allow duplicates to exist among instantiated objects.) When you create your own classes, you'll use the new method to create instances.

Creating Classes

Classes represent a type of an object, such as a book, a whale, a grape, or chocolate. Everybody likes chocolate (may not be true), so let's make a chocolate class:

    class Chocolate
      def eat
        puts "That tasted great!"
      end
    end

Let's take a look at this. Classes are created via the class keyword. After that comes the name of the class. All class names must start with a Capital Letter. By convention, we use CamelCase for class name. So we would create classes like PieceOfChocolate, but not like Piece_of_Chocolate.

The next section defines a class method. A class method is a method that is defined for a particular class. For example, the String class has the length method:

    # outputs "5"
    puts "hello".length

To call the eat method of an instance of the Chocolate class, we would use this code:

    my_chocolate = Chocolate.new
    my_chocolate.eat # outputs "That tasted great!"

You can also call a method by using send

    "hello".send(:length) # outputs "5"
    my_chocolate.send(:eat) # outputs "That tasted great!"

However, using send is rare unless you need to create a dynamic behavior, as we do not need to specify the name of the method as a literal - it can be a variable.

Note that the typical definition of a method in Ruby starts with the keyword def.

You can, however, also use define_method() instead, and combine this with .send, to call arbitrary methods:

  class Foo
    self.class_eval {
      define_method(:'hey there') { puts 'Hey there man!' }
    }
  end
  foo = Foo.new
  foo.send :'hey there' # => Hey there man!

Self

Inside a method of a class, the pseudo-variable self (a pseudo-variable is one that cannot be changed) refers to the current instance. For example:

    class Integer
      def more
        return self + 1
      end
    end
    3.more # -> 4
    7.more # -> 8

Class Methods

You can also create methods that are called on a class rather than an instance. For example:

    class Strawberry
      def Strawberry.color
        return "red"
      end
 
      def self.size
        return "kinda small"
      end
 
      class << self
        def shape
          return "strawberry-ish"
        end
      end
    end
    Strawberry.color # -> "red"
    Strawberry.size  # -> "kinda small"
    Strawberry.shape # -> "strawberry-ish"

Note the three different constructions: ClassName.method_name and self.method_name are essentially the same - outside of a method definition in a class block, self refers to the class itself. The latter is preferred, as it makes changing the name of the class much easier. The last construction, class << self, puts us in the context of the class's "meta-class" (sometimes called the "eigenclass"). The meta-class is a special class that the class itself belongs to. However, at this point, you don't need to worry about it. All this construct does is allow us to define methods without the self. prefix.

Basic Ruby - Exceptions

There is no exceptions chapter at present. Instead, here is a link to a chapter about exceptions from Yukihiro Matsumoto's book, Programming Ruby: The Pragmatic Programmer's Guide [2] More detail and simpler examples about exceptions, by Satish Talim, maybe found in a tutorial at RubyLearning.com [3]

Syntax - Lexicology

Identifiers

An identifier is a name used to identify a variable, method, or class.

As with most languages, valid identifiers consist of alphanumeric characters (A-Za-z0-9) and underscores (_), but may not begin with a digit (0-9). Additionally, identifiers that are method names may end with a question mark (?), exclamation point (!), or equal sign (=).

There are no arbitrary restrictions to the length of an identifier (i.e. it may be as long as you like, limited only by your computer's memory). Finally, there are reserved words which may not be used as identifiers.

Examples:

foobar
ruby_is_simple

Comments

Line comments run from a bare '#' character to the end of the line. Code commenting and documentation is best implemented with Ruby Embedded Documentation. http://www.ruby-doc.org/docs/ProgrammingRuby/html/rdtool.html

Examples:

# this line does nothing; 
print "Hello" # this line prints "Hello"

Embedded Documentation

Example:

=begin
Everything between a line beginning with `=begin' down to
one beginning with `=end' will be skipped by the interpreter.
These reserved words must begin in column 1.
=end

Reserved Words

The following words are reserved in Ruby:

__FILE__  and    def       end     in      or      self   unless
__LINE__  begin  defined?  ensure  module  redo    super  until
BEGIN     break  do        false   next    rescue  then   when
END       case   else      for     nil     retry   true   while
alias     class  elsif     if      not     return  undef  yield

You can find some examples of using them here.

Expressions

Example:

true
(1 + 2) * 3
foo()
if test then okay else not_good end

All variables, literals, control structures, etcetera are expressions. Using these together is called a program. You can divide expressions with newlines or semicolons (;) — however, a newline with a preceding backslash (\) is continued to the following line.

Since in Ruby control structures are expressions as well, one can do the following:

 foo = case 1
       when 1
         true
       else
         false
       end

The above equivalent in a language such as C would generate a syntax error since control structures are not expressions in the C language.

Syntax - Variables and Constants

A variable in Ruby can be distinguished by the characters at the start of its name. There's no restriction to the length of a variable's name (with the exception of the heap size).

Summary

The first character indicates the scope:

  • Local variables - lowercase letter or underscore
  • Instance variables - @
    • In class scope, instance variables belong to the object that is the class
    • To define instance variables on the objects that belong to the class, use @ inside initialize()
  • Class variables - @@
  • Global variables - $
  • Constants - uppercase letter

For more information on variable scopes related to classes, see Ruby Programming/Syntax/Classes.

Local Variables

Example:

foobar
_foobar

A variable whose name begins with a lowercase letter (a-z) or underscore (_) is a local variable or method invocation.

A local variable is only accessible from within the block of its initialization. For example:

i0 = 1
loop {
  i1 = 2
  puts defined?(i0)	# true; "i0" was initialized in the ascendant block
  puts defined?(i1)	# true; "i1" was initialized in this block
  break
}
puts defined?(i0)	# true; "i0 was initialized in this block
puts defined?(i1)	# false; "i1" was initialized in the loop

Instance Variables

Example:

@foobar

A variable whose name begins with '@' is an instance variable of self. An instance variable belongs to the object itself. Uninitialized instance variables have a value of nil.

Class Variables

A class variable is shared by all instances of a class and begins with '@@'. Example:

@@foobar

An important note is that the class variable is shared by all the descendants of the class. Example:

 class Parent
   @@foo = "Parent"
  end
  class Thing1 < Parent
    @@foo = "Thing1"
  end
  class Thing2 < Parent
    @@foo = "Thing2"
  end
  >>Parent.class_eval("@@foo")
  =>"Thing2"
  >>Thing1.class_eval("@@foo")
  =>"Thing2"
  >>Thing2.class_eval("@@foo")
  =>"Thing2"
  >>Thing2.class_variables
  =>[]
  Parent.class_variables
  =>[:@@foo]

This shows us that all our classes were changing the same variable. Class variables behave like global variables which are visible only in the inheritance tree. Because Ruby resolves variables by looking up the inheritance tree *first*, this can cause problems if two subclasses both add a class variable with the same name.

Global Variables

Example:

$foobar

A variable whose name begins with '$' has a global scope; meaning it can be accessed from anywhere within the program during runtime.

Constants

Usage:

FOOBAR

A variable whose name begins with an uppercase letter (A-Z) is a constant. A constant can be reassigned a value after its initialization, but doing so will generate a warning. Every class is a constant.

Trying to access an uninitialized constant raises the NameError exception.

How constants are looked up

Constants are looked up based on your scope or via the scope resolution operator (i.e. '::'). For example

 class A
   A2 = 'a2'
   class B
     def go
       A2 
     end
   end
 end
 instance_of_b = A::B.new
 a2 = A::A2

Another example

class Foo
  BAR = 123
end
puts Foo::BAR   
# => 123

Pseudo Variables

self

Execution context of the current method, which could refer to an instance, class, or module.

nil

The sole-instance of the NilClass class. Expresses nothing.

true

The sole-instance of the TrueClass class. Expresses true.

false

The sole-instance of the FalseClass class. Expresses false.

$1, $2 ... $9

These are contents of capturing groups for regular expression matches. They are local to the current thread and stack frame!

(nil also is considered to be false, and every other value is considered to be true in Ruby.) The value of a pseudo variable cannot be changed. Substitution to a pseudo variable causes an exception to be raised.

Pre-defined Variables

Many pre-defined variables are useful when dealing with regular expressions or Ruby interpreter parameters.

Name Aliases Description
$! $ERROR_INFO[1] The exception information message set by the last 'raise' (last exception thrown).
$@ $ERROR_POSITION[1] Array of the backtrace of the last exception thrown.
$& $MATCH[1] The string matched by the last successful pattern match in this scope.
$` $PREMATCH[1] The string to the left of the last successful match.
$' $POSTMATCH[1] The string to the right of the last successful match.
$+ $LAST_PAREN_MATCH[1] The last group of the last successful match.
$1 to $9 The Nth group of the last successful regexp match.
$~ $LAST_MATCH_INFO[1] The information about the last match in the current scope.
$= $IGNORECASE[1] The flag for case insensitive, nil by default (deprecated).
$/ $INPUT_RECORD_SEPARATOR[1], $RS[1] or $-0 The input record separator, newline by default.
$\ $OUTPUT_RECORD_SEPARATOR[1] or $ORS[1] The output record separator for the print and IO#write. Default is nil.
$, $OUTPUT_FIELD_SEPARATOR[1] or $OFS[1] The output field separator for the print and Array#join.
$; $FIELD_SEPARATOR[1], $FS[1] or $-F The default separator for String#split.
$. $INPUT_LINE_NUMBER[1] or $NR[1] The current input line number of the last file that was read.
$< $DEFAULT_INPUT[1] An object that provides access to the concatenation of the contents of all the files given as command-line arguments, or $stdin (in the case where there are no arguments). Read only.
$FILENAME Current input file from $<. Same as $<.filename.
$> $DEFAULT_OUTPUT[1] The destination of output for Kernel.print and Kernel.printf. The default value is $stdout.
$_ $LAST_READ_LINE[1] The last input line of string by gets or readline.
$0 Contains the name of the script being executed. May be assignable.
$* ARGV[1] Command line arguments given for the script. Also known as ARGV
$$ $PROCESS_ID[1], $PID[1] or Process.pid The process number of the Ruby running this script.
$? $CHILD_STATUS[1] The status of the last executed child process.
$: $LOAD_PATH Load path for scripts and binary modules by load or require.
$" $LOADED_FEATURES or $-I The array contains the module names loaded by require.
$stderr The current standard error output.
$stdin The current standard input.
$stdout The current standard output.
$-d $DEBUG The status of the -d switch. Assignable.
$-K $KCODE Character encoding of the source code.
$-v $VERBOSE The verbose flag, which is set by the -v switch.
$-a True if option -a ("autosplit" mode) is set. Read-only variable.
$-i If in-place-edit mode is set, this variable holds the extension, otherwise nil.
$-l True if option -l is set ("line-ending processing" is on). Read-only variable.
$-p True if option -p is set ("loop" mode is on). Read-only variable.
$-w True if option -w is set.

To avoid the criticism that two-character, punctuation-based variable names are cryptic or confusing, part of the standard library is "English" which defines the longer names listed in the table above. To include these names, just require the English library as follows.[1]

Without ‘English’:

   $\ = ' -- '
   "waterbuffalo" =~ /buff/
   print $", $', $$, "\n"

With English:

   require "English"
   
   $OUTPUT_FIELD_SEPARATOR = ' -- '
   "waterbuffalo" =~ /buff/
   print $LOADED_FEATURES, $POSTMATCH, $PID, "\n"

Pre-defined Constants

Note that there are some pre-defined constants at parse time, as well, namely

 __FILE__   (current file)
 __LINE__   (current line)

and

 __dir__    (current directory)
 __method__ (current method)

(new in Ruby 2.0)

A list of predefined global constants can be found in the Ruby language documentation.[2] Among the notable ones are:

Global constant name Description
STDIN The standard input. The default value for $stdin.
STDOUT The standard output. The default value for $stdout.
STDERR The standard error output. The default value for $stderr.
ENV The hash contains current environment variables.
ARGV An Array of command line arguments given for the script.
RUBY_VERSION The Ruby language version, e.g., ruby -e 'puts RUBY_VERSION' will print 2.7.0.
RUBY_RELEASE_DATE The release date string, e.g., 2019-12-25.
RUBY_PLATFORM The platform identifier, e.g., x86_64-linux-gnu
RUBY_PATCHLEVEL The patchlevel for this Ruby, e.g., 0. If this is a development build of Ruby the patchlevel will be -1.

Notes

  1. a b c d e f g h i j k l m n o p q r s t u v w x y z English.rb from the Ruby 1.9.2 Standard Library Documentation
  2. The document on pre-defined global variables and constants from the official Ruby documentation
Previous: Lexicology Index Next: Literals

Syntax - Literals

Numerics

123                       # Fixnum
-123                      # Fixnum (signed)
1_123                     # Fixnum (underscore is ignored)
-543                      # Negative Fixnum
123_456_789_123_456_789   # Bignum
123.45                    # Float
1.2e-3                    # Float
123.45r                   # Rational, introduced in ruby 2.1
0xaabb                    # (Hexadecimal) Fixnum
0377                      # (Octal) Fixnum
-0b1010                   # (Binary [negated]) Fixnum
0b001_001                 # (Binary) Fixnum
?a                        # ASCII character code for 'a' (97)
?\C-a                     # Control-a (1)
?\M-a                     # Meta-a (225)
?\M-\C-a                  # Meta-Control-a (129)

Note: the meaning of "?x" notation has been changed. In ruby 1.9 this means not an ASCII numeric code but a string i.e. ?a == "a"

Strings

Examples:

"this is a string"
=> "this is a string"

"three plus three is #{3+3}"
=> "three plus three is 6" 

foobar = "blah"
"the value of foobar is #{foobar}"
=> "the value of foobar is blah" 

'the value of foobar is #{foobar}'
=> "the value of foobar is \#{foobar}"

A string expression begins and ends with a double or single-quote mark. Double-quoted string expressions are subject to backslash notation and interpolation. A single-quoted string expression isn't; except for \' and \\.

Backslash Notation

Also called escape characters or escape sequences, they are used to insert special characters in a string.

Example:

"this is a\ntwo line string"
"this string has \"quotes\" in it"
Escape Sequence Meaning
\n newline (0x0a)
\s space (0x20)
\r carriage return (0x0d)
\t tab (0x09)
\v vertical tab (0x0b)
\f formfeed (0x0c)
\b backspace (0x08)
\a bell/alert (0x07)
\e escape (0x1b)
\nnn character with octal value nnn
\xnn character with hexadecimal value nn
\unnnn Unicode code point U+nnnn (Ruby 1.9 and later)
\u{nnnnn} Unicode code point U+nnnnn with more than four hex digits must be enclosed in curly braces
\cx control-x
\C-x control-x
\M-x meta-x
\M-\C-x meta-control-x
\x character x itself (for example \" is the double quote character)

For characters with decimal values, you can do this:

"" << 197 # add decimal value 197 to a string

=> Å

or embed them thus:

"#{197.chr}"

Interpolation

Interpolation allows Ruby code to appear within a string. The result of evaluating that code is inserted into the string:

 "1 + 2 = #{1 + 2}"    # => "1 + 2 = 3"
 #{expression}

The expression can be just about any Ruby code. Ruby is pretty smart about handling string delimiters that appear in the code and it generally does what you want it to do. The code will have the same side effects as it would outside the string, including any errors:

"the meaning of life is #{1/0}"
=> divided by 0 (ZeroDivisionError)

The % Notation

There is also a Perl-inspired way to quote strings: by using % (percent character) and specifying a delimiting character, for example:

%{78% of statistics are "made up" on the spot}
=> "78% of statistics are \"made up\" on the spot"

Any single non-alpha-numeric character can be used as the delimiter, %[including these], %?or these?, %~or even these things~. By using this notation, the usual string delimiters " and ' can appear in the string unescaped, but of course the new delimiter you've chosen does need to be escaped. However, if you use %(parentheses), %[square brackets], %{curly brackets} or %<pointy brackets> as delimiters then those same delimiters can appear unescaped in the string as long as they are in balanced pairs:

%(string (syntax) is pretty flexible)
=> "string (syntax) is pretty flexible"

A modifier character can appear after the %, as in %q[], %Q[], %x[] - these determine how the string is interpolated and what type of object is produced:

Modifier Meaning
%q[ ] Non-interpolated String (except for \\, \[, and \])
%Q[ ] Interpolated String (default)
%r[ ] Interpolated Regexp (flags can appear after the closing delimiter)
%i[ ] Non-interpolated Array of symbols, separated by whitespace (after Ruby 2.0)
%I[ ] Interpolated Array of symbols, separated by whitespace (after Ruby 2.0)
%w[ ] Non-interpolated Array of words, separated by whitespace
%W[ ] Interpolated Array of words, separated by whitespace
%x[ ] Interpolated shell command
%s[ ] Non-interpolated symbol

Here are some more examples:

%Q{one\ntwo\n#{ 1 + 2 }}
=> "one\ntwo\n3"

%q{one\ntwo\n#{ 1 + 2 }}
=> "one\\ntwo\\n#{ 1 + 2 }"

%r/#{name}/i
=> /nemo/i

%w{one two three}
=> ["one", "two", "three"]

%i{one two three} # after Ruby 2.0
=> [:one, :two, :three]

%x{ruby --copyright}
=> "ruby - Copyright (C) 1993-2009 Yukihiro Matsumoto\n"

"Here document" notation

There is yet another way to make a string, known as a 'here document', where the delimiter itself can be any string:

string = <<END
on the one ton temple bell
a moon-moth, folded into sleep,
sits still.
END

The syntax begins with << and is followed immediately by the delimiter. To end the string, the delimiter appears alone on a line.

There is a slightly nicer way to write a here document which allows the ending delimiter to be indented by whitespace:

string = <<-FIN
           on the one-ton temple bell
           a moon-moth, folded into sleep
           sits still.

           --Taniguchi Buson, 18th century; translated by X. J. Kennedy
         FIN

To use non-alpha-numeric characters in the delimiter, it can be quoted:

string = <<-"."
           Orchid - breathing
           incense into
           butterfly's wings.

           --Matsuo Basho; translated by Lucien Stryk
         .

Here documents are interpolated, unless you use single quotes around the delimiter.

The rest of the line after the opening delimiter is not interpreted as part of the string, which means you can do this:

strings = [<<END, "short", "strings"]
a long string
END

=> ["a long string\n", "short", "strings"]

You can even "stack" multiple here documents:

string = [<<ONE, <<TWO, <<THREE]
  the first thing
ONE
  the second thing
TWO
  and the third thing
THREE
=> ["the first thing\n", "the second thing\n", "and the third thing\n"]

And you can even apply methods:

s = <<END.chomp.upcase # Stripped of ending new-line and uppercased.
abc
END
=> "ABC"

Command Expansion

You can execute shell commands and run any external programs, and get the output, with backticks-quoted strings.

# Print contents of current directory, just like in console window.
puts `dir`
# Resolve a domain name to its IP address.
domain = 'ruby-lang.org'
ip = `nslookup #{domain}`.match(/\d+\.\d+\.\d+\.\d+/).to_s # => 151.101.85.178
# Download this web-page with "curl", displaying the progress, then find and print an example from it.
puts `curl https://en.wikibooks.org/w/index.php?title=Ruby_Programming/Syntax/Literals`.encode('utf-8')
  .match(%r(<h2(?:.(?!</h2>))*Numerics.*?(?=<h2))imsu).to_s    # Reducing to one section.
  .match(%r((?<=<pre>).*?(?=</pre>))imsu ).to_s                # Reducing to an example in it.

Regular Expressions

regex_one = /chapter_\d+/i #=> /chapter_\d+/i
regex_two = %r(/chapter_\d+)i #=> /\/chapter_\d+/i

Arrays

An array is a collection of objects indexed by a non-negative integer. You can create an array object by writing Array.new, by writing an optional comma-separated list of values inside square brackets, or if the array will only contain string objects, a space-delimited string preceded by %w.

array_one   = Array.new
array_two   = []                # shorthand for Array.new
array_three = ["a", "b", "c"]   # array_three contains "a", "b" and "c"
array_four  = %w[a b c d e f g] # array_four also contains "a", "b" and "c"
array_three[0]                # => "a"
array_three[2]                # => "c"
array_four[0]                 # => "a"
#negative indices are counted back from the end
array_four[-2]                # => "f"
#[start, count] indexing returns an array of count objects beginning at index start
array_four[1,3]               # => ["b", "c", "d"]
#using ranges. The end position is included with two periods but not with three
array_four[0..4]              # => ["a", "b", "c", "d", "e"]
array_four[0...4]             # => ["a", "b", "c", "d"]

The last method, using %w, is in essence shorthand for the String method split when the substrings are separated by whitespace only. In the following example, the first two ways of creating an array of strings are functionally identical while the last two create very different (though both valid) arrays.

 array_one   = %w'apple orange pear'            # => ["apple", "orange", "pear"]
 array_two   = 'apple orange pear'.split        # => ["apple", "orange", "pear"]
 array_one   == array_two                       # => true
 array_three = %w'dog:cat:bird'                 # => ["dog:cat:bird"]
 array_four  = 'dog:cat:bird'.split(':')        # => ["dog", "cat", "bird"]
 array_three == array_four                      # => false

Hashes

Hashes are basically the same as arrays, except that a hash not only contains values, but also keys pointing to those values. Each key can occur only once in a hash. A hash object is created by writing Hash.new or by writing an optional list of comma-separated key => value pairs inside curly braces.

hash_one   = Hash.new
hash_two   = {}                             # shorthand for Hash.new
hash_three = {"a" => 1, "b" => 2, "c" => 3} #=> {"a"=>1, "b"=>2, "c"=>3}

Usually Symbols are used for Hash keys (allows for quicker access), so you will see hashes declared like this:

hash_sym   = { :a => 1, :b => 2, :c => 3}   #=> {:b=>2, :c=>3, :a=>1}
hash_sym   = { a: 1, b: 2, c: 3}            #=> {:b=>2, :c=>3, :a=>1}

The latter form was introduced in Ruby 1.9.

Hash ordering

Note that with 1.8, iterating over hashes will iterate over the key value pairs in a "random" order. Beginning with 1.9, it will iterate over them in the order they were inserted. Note however, that if you reinsert a key without first deleting it, or change an existing key's value, the key's order in iteration does not change.

>> a = {:a => 1, :b => 2, :c => 3}
=> {:a=>1, :b=>2, :c=>3}
>> a.keys # iterate over, show me the keys
=> [:a, :b, :c]
>> a[:b] = 2
> a.keys
=> [:a, :b, :c] # same order
>> a.delete(:b)
>> a[:b] = 4 # re insert now
=> 4
>> a.keys
=> [:a, :c, :b] # different order

Ranges

A range represents a subset of all possible values of a type, to be more precise, all possible values between a start value and an end value.

This may be:

  • All integers between 0 and 5.
  • All numbers (including non-integers) between 0 and 1, excluding 1.
  • All characters between 't' and 'y'.

In Ruby, these ranges are expressed by:

0..5
0.0...1.0
't'..'y'

Therefore, ranges consist of a start value, an end value, and whether the end value is included or not (in this short syntax, using two . for including and three . for excluding).

A range represents a set of values, not a sequence. Therefore,

5..0

though syntactically correct, produces a range of length zero.

Ranges can only be formed from instances of the same class or subclasses of a common parent, which must be Comparable (implementing <=>).

Ranges are instances of the Range class, and have certain methods, for example, to determine whether a value is inside a range:

r = 0..5
puts r === 4  # => true
puts r === 7  # => false

For detailed information of all Range methods, consult the Range class reference.

Here is a tutorial on their use.

Syntax - Operators

Operators

Complete List and Precedence

Operator Name/meaning Arguments Precedence[1] Association
! Boolean NOT Unary 1 Right
~ Bitwise complement Unary 1 Right
+ Unary plus (no effect) Unary 1 Right
** Exponentiation Binary 1 Right
- Unary minus (reverse sign) Unary 2 Right
* Multiplication Binary 3 Left
/ Division Binary 3 Left
% Modulo (remainder) Binary 3 Left
+ Addition or concatenation Binary 4 Left
- Subtraction Binary 4 Left
<< Bitwise shift left or append (<< and <<- are also used in "here doc" notation) Binary 5 Left
>> Bitwise shift right Binary 5 Left
& Bitwise AND Binary 6 Left
| Bitwise OR Binary 7 Left
^ Bitwise XOR Binary 7 Left
< Less-than Binary 8 Left
<= Less-than or equal-to Binary 8 Left
> Greater-than Binary 8 Left
>= Greater-than or equal to Binary 8 Left
== Equal (evaluate to the same value) Binary 9 N/A
=== "Case equality", "case subsumption" or "three equals" operator. A === B if B is a member of the set of A. Operation varies considerably depending on the data types of A and B. Binary 9 N/A
!= Not equal Binary 9 N/A
=~ Pattern match Binary 9 N/A
!~ Negative pattern match Binary 9 N/A
<=> A <=> B evaluates to -1, 0, or 1; if A is less-than, equal-to, or greater-than B, respectively Binary 9 N/A
&& Boolean AND Binary 10 Left
|| Boolean OR Binary 11 Left
.. Range creation, boolean flip-flop Binary 12 N/A
... Open-ended range creation, boolean flip-flop Binary 12 N/A
?: A?B:C evaluates to B if A is true, or C if A is false Trinary 13 Right
rescue Modifier for catching exceptions e.g. array[3] rescue nil Binary 14 Left
= Assignment Binary 15 Right
**= A **=B does A = A ** B Binary 15 Right
*= A *=B does A = A * B Binary 15 Right
/= A /=B does A = A / B Binary 15 Right
%= A %=B does A = A % B Binary 15 Right
+= A +=B does A = A + B Binary 15 Right
-= A -=B does A = A – B Binary 15 Right
<<= A <<=B does A = A << B Binary 15 Right
>>= A >>=B does A = A >> B Binary 15 Right
&&= A &&=B assigns B to A if A is true or not nil Binary 15 Right
&= A &=B does A = A & B Binary 15 Right
||= A ||=B assigns B to A if A is nil or false Binary 15 Right
|= A |= B does A = A | B Binary 15 Right
^= A ^=B does A = A ^ B Binary 15 Right
defined? nil if the expression cannot be evaluated (e.g. unset variable) Unary 16 N/A
not Boolean NOT Unary 17 Right
and Boolean AND Binary 18 Left
or Boolean OR Binary 18 Left
if Conditional, e.g. print x if x Binary 19 N/A
unless Negative conditional, e.g. x = 0 unless x Binary 19 N/A
while Loop conditional, e.g. print x += 1 while (x < 10) Binary 19 N/A
until Loop conditional, e.g. print x += 1 until (x == 10) Binary 19 N/A

Higher precedence (lower number in the above table) operators have their immediate arguments evaluated first. Precedence order can be altered with () blocks. For example, because * has higher precedence than +, then:
1 + 2 * 3 == 7
(1 + 2) * 3 == 9

Association direction controls which operators have their arguments evaluated first when multiple operators with the same precedence appear in a row. For example, because - has left association:

1 – 2 – 3 == (1 – 2) – 3 == -1 – 3 == -4

instead of:

1 – 2 – 3 == 1 – (2 – 3) == 1 - -1 == 0

Because ** has right association:

2 ** 3 ** 2 == 2 ** (3 ** 2) == 2 ** 9 == 512

instead of:

2 ** 3 ** 2 == (2 ** 3) ** 2 == 8 ** 2 == 64

{} blocks have lower precedence than the above operators, followed by do/end blocks. Array accesses with [] can be thought of as having a higher precedence than any above operator.

The operators ** through !~ can be overridden (defined for new classes, or redefined for existing operations).

Note that rescue, if, unless, while, and until are operators when used as modifiers in one-liners (as in the above examples) but can also be used as keywords.

Other operators

The dot operator . is used for calling methods on objects, also known as passing a message to the object.

Ruby 2.3.0 introduced the safe navigation operator &., also known as the "lonely operator".[2] This allows replacing

x = foo && foo.bar && foo.bar.baz

with

x = foo&.bar&.baz

An equivalent .dig() method was introduced for hashes and arrays:

hash_variable.dig(:foo, :bar, :baz)
array_variable.dig(1, 0, 2)

are safer versions of:

hash_variable[:foo][:bar][:baz]
array_variable[1][0][2]

The safe navigation operator will raise an error if a requested method, key, or index is not available; unlike the technique of using try() for this purpose, which will return nil.[3]

Yukihiro Matsumoto considered ! ?. and .? before settling on &. because:[4]

  • ?. conflicts with *?
  • ?. is used by other languages, thus .? is confusingly similar but different
  • ! conflicts with "not" logic
  • ? is already used by convention for functions that return booleans
  • &. is reminiscent of the && syntax the operator is replacing

!! is sometimes seen, but this is simply the ! operator twice. It is used to force the following expression to evaluate to a boolean. This technique is considered non-idiomatic and poor programming practice, because there are more explicit ways to force such a conversion (which is rarely needed to begin with).

Assignment

Assignment in Ruby is done using the equal operator "=". This is both for variables and objects, but since strings, floats, and integers are actually objects in Ruby, you're always assigning objects.

Examples:

  myvar = 'myvar is now this string'
  var = 321
  dbconn = Mysql::new('localhost','root','password')

Self assignment

  x = 1           #=>1
  x += x          #=>2
  x -= x          #=>0
  x += 4          #=>x was 0 so x= + 4 # x is positive 4
  x *= x          #=>16
  x **= x         #=>18446744073709551616 # Raise to the power
  x /= x          #=>1

A frequent question from C and C++ types is "How do you increment a variable? Where are ++ and -- operators?" In Ruby, one should use x+=1 and x-=1 to increment or decrement a variable.

  x = 'a'
  x.succ!         #=>"b" : succ! method is defined for String, but not for Integer types

Multiple assignments

Examples:

  var1, var2, var3 = 10, 20, 30
  var1           #=> 10
  var2           #=> 20
  var3           #=> 30

  myArray=%w(John Michel Fran Doug) # %w() can be used as syntactic sugar to simplify array creation
  var1,var2,var3,var4=*myArray
  puts var1           #=>John
  puts var4           #=>Doug

  names,school=myArray,'St. Whatever'
  names               #=>["John", "Michel", "Fran", "Doug"]
  school              #=>"St. Whatever"

Conditional assignment

  x = find_something() #=>nil
  x ||= "default"      #=>"default" : value of x will be replaced with "default", but only if x is nil or false
  x ||= "other"        #=>"default" : value of x is not replaced if it already is other than nil or false

Operator ||= is a shorthand form that closely resembles the expression:[5]

 x = x || "default"

Operator ||= can be shorthand for code like:

  x = "(some fallback value)" unless respond_to? :x or x

In same way &&= operator works:

  x = get_node() #=>nil
  x &&= x.next_node #=> nil : x will be set to x.next_node, but only if x is NOT nil or false
  x = get_node() #=>Some Node
  x &&= x.next_node #=>Next Node

Operator &&= is a shorthand form of the expression:

 x && x = x.get_node()

Scope

In Ruby there's a local scope, a global scope, an instance scope, and a class scope.

Local Scope

Example:

 var = 2
 4.times do |x|
   puts x = x*var
 end
 #=>
 0
 2
 4
 6
 puts x
 #=> undefined local variable or method `x' for main:Object (NameError)

This error appears because this x(toplevel) is not the x(local) inside the do..end block the x(local) is a local variable to the block, whereas when trying the puts x(toplevel) we're calling a x variable that is in the top level scope, and since there's not one, Ruby protests.

Global scope

 $global = 0
 4.times do |var|
   $global = $global + var
   puts "var #{var}  global #{$global}"
 end
 #=>
 var 0  global 0
 var 1  global 1
 var 2  global 3
 var 3  global 6
 
 puts $global
 #=> 6

This output is given because prefixing a variable with a dollar sign makes the variable a global.

Instance scope

Within methods of a class, you can share variables by prefixing them with an @.

 class A
   def setup
     @instvar = 1
   end
   def go
     @instvar = @instvar*2
     puts @instvar
   end
 end
 instance = A.new
 instance.setup
 instance.go
 #=> 2
 instance.go
 #=> 4

Class scope

A class variable is one that is like a "static" variable in Java. It is shared by all instances of a class.

 class A
   @@classvar = 1
   def go
     @@classvar = @@classvar*2
     puts @@classvar
   end
 end
 instance = A.new
 instance.go
 #=> 2
 instance = A.new
 instance.go
 #=> 4 -- variable is shared across instances

Here's a demo showing the various types:

$variable
 class Test
   def initialize(arg1='kiwi')
     @instvar=arg1
     @@classvar=@instvar+' told you so!!'
     localvar=@instvar
   end
   def print_instvar
     puts @instvar
   end
   def print_localvar
     puts @@classvar
     puts localvar
   end
 end
 var=Test.new
 var.print_instvar              #=>"kiwi", it works because a @instance_var can be accessed inside the class
 var.print_localvar             #=>undefined local variable or method 'localvar' for #<Test:0x2b36208 @instvar="kiwi"> (NameError).

This will print the two lines "kiwi" and "kiwi told you so!!", then fail with a undefined local variable or method 'localvar' for #<Test:0x2b36208 @instvar="kiwi"> (NameError). Why? Well, in the scope of the method print_localvar there doesn't exists localvar, it exists in method initialize(until GC kicks it out). On the other hand, class variables '@@classvar' and '@instvar' are in scope across the entire class and, in the case of @@class variables, across the children classes.

 class SubTest < Test
   def print_classvar
     puts @@classvar
   end
 end
 newvar=SubTest.new              #newvar is created and it has @@classvar with the same value as the var  instance of Test!!
 newvar.print_classvar           #=>kiwi told you so!! 

Class variables have the scope of parent class AND children, these variables can live across classes, and can be affected by the children actions ;-)

 class SubSubTest < Test
   def print_classvar
     puts @@classvar
   end
   def modify_classvar
     @@classvar='kiwi kiwi waaai!!'
   end
 end
 subtest=SubSubTest.new
 subtest.modify_classvar          #lets add a method that modifies the contents of @@classvar in  SubSubTest
 subtest.print_classvar

This new child of Test also has @@classvar with the original value newvar.print_classvar. The value of @@classvar has been changed to 'kiwi kiwi waaai!!' This shows that @@classvar is "shared" across parent and child classes.

Default scope

When you don't enclose your code in any scope specifier, ex:

 @a = 33

it affects the default scope, which is an object called "main".

For example, if you had one script that says

@a = 33
require 'other_script.rb'

and other_script.rb says

puts @a
 #=> 33

They could share variables.

Note however, that the two scripts don't share local variables.

Local scope gotchas

Typically when you are within a class, you can do as you'd like for definitions, like.

class A
  a = 3
  if a == 3

    def go
       3
    end
  else
    def go
       4
    end
  end

end

And also, procs "bind" to their surrounding scope, like

 a = 3
 b = proc { a }
 b.call # 3 -- it remembered what a was

However, the "class" and "def" keywords cause an *entirely new* scope.

class A
  a = 3
  def go
     return a # this won't work!
  end
end

You can get around this limitation by using define_method, which takes a block and thus keeps the outer scope (note that you can use any block you want, to, too, but here's an example).

class A
   a = 3
  define_method(:go) {
      a
  }
end

Here's using an arbitrary block

a = 3
PROC = proc { a } # gotta use something besides a local
# variable because that "class" makes us lose scope.

class A
  define_method(:go, &PROC)
end

or here

 class A
 end
a = 3
 A.class_eval do
   define_method(:go) do
       puts a
   end
end

Logical And

The binary "and" operator will return the logical conjunction of its two operands. It is the same as "&&" but with a lower precedence. Example:

a = 1
b = 2
c = nil
puts "yay all my arguments are true" if a and b
puts "oh no, one of my argument is false" if a and c

Logical Or

The binary "or" operator will return the logical disjunction of its two operands. It is the same as "||" but with a lower precedence. Example:

a = nil
b = "foo"
c = a || b  # c is set to "foo" it's the same as saying c = (a || b)
c = a or b  # c is set to nil   it's the same as saying (c = a) || b which is not what you want.

References

  1. http://ruby-doc.org/core-2.4.0/doc/syntax/precedence_rdoc.html
  2. https://www.ruby-lang.org/en/news/2015/12/25/ruby-2-3-0-released/
  3. http://blog.rubyeffect.com/ruby-2-3s-lonely-operator/
  4. https://bugs.ruby-lang.org/issues/11537
  5. http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html

Syntax - Control Structures

Control Structures

Conditional Branches

Ruby can control the execution of code using Conditional branches. A conditional Branch takes the result of a test expression and executes a block of code depending whether the test expression is true or false. If the test expression evaluates to the constant false or nil, the test is false; otherwise, it is true. Note that the number zero is considered true, whereas many other programming languages consider it false.

In many popular programming languages, conditional branches are statements. They can affect which code is executed, but they do not result in values themselves. In Ruby, however, conditional branches are expressions. They evaluate to values, just like other expressions do. An if expression, for example, not only determines whether a subordinate block of code will execute, but also results in a value itself. If no block is executed, the if expression results in nil. For instance, the following if expression evaluates to 3:

 if true
   3
 end

Ruby's conditional branches are explained below.

if expression

Examples:

 a = 5
 if a == 4
   a = 7
 end
 print a # prints 5 since the if-block isn't executed

You can also put the test expression and code block on the same line if you use then:

 if a == 4 then a = 7 end
 #or
 if a == 4: a = 7 end
 #Note that the ":" syntax for if one line blocks do not work anymore in ruby 1.9. Ternary statements still work

This is equal to:

 a = 5
 a = 7 if a == 4
 print a # prints 5 since the if-block isn't executed

unless expression

The unless-expression is the opposite of the if-expression, the code-block it contains will only be executed if the test expression is false.

Examples:

 a = 5
 unless a == 4
   a = 7
 end
 print a # prints 7 since the unless-block is executed

The unless expression is almost exactly like a negated if expression:

 if !expression # is equal to using unless expression

The difference is that the unless does not permit a following elsif. And there is no elsunless.

Like the if-expression you can also write:

 a = 5
 a = 7 unless a == 4
 print a # prints 7 since the unless-block is executed

The "one-liners" are handy when the code executed in the block is one line only.

if-elsif-else expression

The elsif (note that it's elsif and not elseif) and else blocks give you further control of your scripts by providing the option to accommodate additional tests. The elsif and else blocks are considered only if the if test is false. You can have any number of elsif blocks but only one if and one else block.

Syntax:

 if expression
   ...code block...
 elsif another expression
   ...code block...
 elsif another expression
   ...code block...
 else
   ...code block...
 end

short-if expression (aka ternary operator)

The "short-if" statement provides you with a space-saving way of evaluating an expression and returning a value.

The format is:

 result = (condition) ? (expression-if-true) : (expression-if-false)

It is also known as the ternary operator and it is suggested to only use this syntax for minor tasks, such as string formatting, because of poor code readability that may result.

 irb(main):037:0> true ? 't' : 'f'
 => "t"
 irb(main):038:0> false ? 't' : 'f'
 => "f"

This is very useful when doing string concatenation among other things.

Example:

 a = 5
 plus_or_minus = '+'
 print "The number #{a}#{plus_or_minus}1 is: #{plus_or_minus == '+' ? (a+1).to_s : (a-1).to_s}."

Also, this can be written as:

 result = if condition then expression-1 else expression-2 end

Assignments can be made as:

 result = (value-1 if expression-1) || (value-2 if expression-2)

case expression

An alternative to the if-elsif-else expression (above) is the case expression. Case in Ruby supports a number of syntaxes. For example, suppose we want to determine the relationship of a number (given by the variable a) to 5. We could say:

 a = 1
 case 
 when a < 5 then puts "#{a} is less than 5"    
 when a == 5 then puts "#{a} equals 5"   
 when a > 5 then puts "#{a} is greater than 5" 
 end

Note that, as with if, the comparison operator is ==. The assignment operator is =. Though Ruby will accept the assignment operator:

   when a = 5 then puts "#{a} equals 5"   # WARNING! This code CHANGES the value of a!

this is not what we want! Here, we want the comparison operator.

A more concise syntax for case is to imply the comparison:

 case a
 when 0..4 then puts "#{a} is less than 5"    
 when 5 then puts "#{a} equals 5" 
 when 5..10 then puts "#{a} is greater than 5" 
 else puts "unexpected value #{a} "         # Just in case "a" is bigger than 10 or negative.
 end

Note: because the ranges are explicitly stated, it is a good coding practice to handle unexpected values of a. This concise syntax is perhaps most useful when we know in advance what values to expect. For example:

 a = "apple"
 case a
 when "vanilla" then "a spice"    
 when  "spinach" then "a vegetable" 
 when "apple" then "a fruit" 
 else "an unexpected value"
 end

If entered into IRB this gives:

 => "a fruit"

Other ways to use case and variations on its syntax may be seen at Linuxtopia Ruby Programming [4]

Loops

while

The while statement in Ruby is very similar to if and to other languages' while (syntactically):

while <expression>
  <...code block...>
end

The code block will be executed again and again, as long as the expression evaluates to true.

Also, like if and unless, the following is possible:

<...code...> while <expression>

Note the following strange case works...

 line = readline.chomp while line != "what I'm looking for"

So if local variable line has no existence prior to this line, on seeing it for the first time it has the value nil when the loop expression is first evaluated.

until

The until statement is similar to the while statement in functionality. Unlike the while statement, the code block for the until loop will execute as long as the expression evaluates to false.

until <expression>
  <...code block...>
end

Keywords

return

return value causes the method in which it appears to exit at that point and return the value specified.

Note that if a method has no return statement then the value of the last statement is implicitly returned.

Syntax - Method Calls

A method in Ruby is a set of expressions that returns a value. With methods, one can organize their code into subroutines that can be easily invoked from other areas of their program. Other languages sometimes refer to this as a function. A method may be defined as a part of a class or separately.

Method Calls

Methods are called using the following syntax:

method_name(parameter1, parameter2,)

With or without parameters, Ruby allows method calls without parentheses:

method_name

results = method_name parameter1, parameter2

Parentheses are needed to chain method calls; for example:

results = method_name(parameter1, parameter2).reverse

Method Definitions

Methods are defined using the keyword def followed by the method name. Method parameters are specified between parentheses following the method name. The method body is enclosed by this definition on the top and the word end on the bottom. By convention method names that consist of multiple words have each word separated by an underscore.

Example:

def output_something(value)
  puts value 
end

Return Values

Methods return the value of the last statement executed. The following code returns the value x+y.

def calculate_value(x,y)
  x + y
end

An explicit return statement can also be used to return from function with a value, prior to the end of the function declaration. This is useful when you want to terminate a loop or return from a function as the result of a conditional expression.

Note, if you use "return" within a block, you actually will jump out from the function, probably not what you want. To terminate block, use break. You can pass a value to break which will be returned as the result of the block:

six = (1..10).each {|i| break i if i > 5}

In this case, six will have the value 6.

Default Values

A default parameter value can be specified during method definition to replace the value of a parameter if it is not passed into the method.

def some_method(value='default', arr=[])
  puts value
  puts arr.length
end

some_method('something')

The method call above will output:

  something
  0

The following is a syntax error in Ruby 1.8

  def foo( i = 7, j ) # Syntax error in Ruby 1.8.7 Unexpected ')', expecting '='
    return i + j
  end

The above code will work in 1.9.2 and will be logically equivalent to the snippet below

  def foo( j, i = 7)
    return i + j
  end

Variable Length Argument List, Asterisk Operator

The last parameter of a method may be preceded by an asterisk(*), which is sometimes called the 'splat' operator. This indicates that more parameters may be passed to the function. Those parameters are collected up and an array is created.

  def calculate_value(x,y,*otherValues)
    puts otherValues
  end
  
  calculate_value(1,2,'a','b','c')

In the example above the output would be ['a', 'b', 'c'].

The asterisk operator may also precede an Array argument in a method call. In this case the Array will be expanded and the values passed in as if they were separated by commas.

  arr = ['a','b','c']
  calculate_value(*arr)

has the same result as:

  calculate_value('a','b','c')

Another technique that Ruby allows is to give a Hash when invoking a function, and that gives you best of all worlds: named parameters, and variable argument length.

  def accepts_hash( var )
    print "got: ", var.inspect # will print out what it received
  end
  
  accepts_hash :arg1 => 'giving arg1', :argN => 'giving argN'
  # => got: {:argN=>"giving argN", :arg1=>"giving arg1"}

You see, the arguments for accepts_hash got rolled up into one hash variable. This technique is heavily used in the Ruby On Rails API.

Also note the missing parenthesis around the arguments for the accepts_hash function call, and notice that there is no { } Hash declaration syntax around the :arg1 => '...' code, either. The above code is equivalent to the more verbose:

  accepts_hash( :arg1 => 'giving arg1', :argN => 'giving argN' )  # argument list enclosed in parens
  accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } ) # hash is explicitly created

Now, if you are going to pass a code block to function, you need parentheses.

  accepts_hash( :arg1 => 'giving arg1', :argN => 'giving argN' )  { |s| puts s }
  accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } )  { |s| puts s } 
  # second line is more verbose, hash explicitly created, but essentially the same as above


In versions of Ruby since Ruby 2.0, it is also possible to use the new built-in keyword arguments that make above technique somewhat easier. The new syntax is as follows:

def test_method(a, b, c:true, d:false) 
   puts  a,b,c,d
end

Above function can now be called as test_method(1,2), test_method(1,2, c: somevalue), test_method(1,2, d:someothervalue), test_method(1,2, c:somevalue, d:someothervalue) or even test_method(1,2, d: someothervalue, c: somevalue) . In this example, parentheses are again not required unless you want to chain the result to another function or method right away. Note that this does mean that you 'have' to pass on names for (in this case) the 'c' and 'd' values you pass into the function, whenever you want to include them Calling the method like test_method(1,2,3,4) will not work.

Keyword Arguments are especially helpful whenever there is a lot of non-required options that might be passed into a function. Specifying the names whenever they are used makes the resulting function calls very readable.

The Ampersand Operator

Much like the asterisk, the ampersand(&) may precede the last parameter of a function declaration. This indicates that the function expects a code block to be passed in. A Proc object will be created and assigned to the parameter containing the block passed in.

Also similar to the ampersand operator, a Proc object preceded by an ampersand during a method call will be replaced by the block that it contains. Yield may then be used.

  def method_call
    yield
  end

  method_call(&someBlock)

Understanding blocks, Procs and methods

Introduction

Ruby provides the programmer with a set of very powerful features borrowed from the domain of functional programming, namely closures, higher-order functions, and first-class functions [1]. These features are implemented in Ruby by means of code blocks, Proc objects, and methods (that are also objects)—concepts that are closely related and yet differ in subtle ways. In fact, I found myself quite confused about this topic, having difficulty understanding the difference between blocks, procs, and methods as well as unsure about the best practices of using them. Additionally, having some background in Lisp and years of Perl experience, I was unsure of how the Ruby concepts map to similar idioms from other programming languages like Lisp’s functions and Perl’s subroutines. Sifting through hundreds of newsgroup posts, I saw that I am not the only one with this problem and, in fact, quite a lot of “Ruby Nubies” struggle with the same ideas.

In this article I lay out my understanding of this facet of Ruby, which comes as a result of extensive research of Ruby books, documentation, and comp.lang.ruby, in sincere hope that other people will find it useful as well.

Procs

Shamelessly ripping from the Ruby documentation, Procs are defined as follows: Proc objects are blocks of code that have been bound to a set of local variables. Once bound, the code may be called in different contexts and still access those variables.

A useful example is also provided:

  def gen_times(factor)
      return Proc.new {|n| n*factor }
  end
  
  times3 = gen_times(3)      # 'factor' is replaced with 3
  times5 = gen_times(5)
  
  times3.call(12)               #=> 36
  times5.call(5)                #=> 25
  times3.call(times5.call(4))   #=> 60

Procs play the role of functions in Ruby. It is more accurate to call them function objects, since like everything in Ruby they are objects. Such objects have a name in the folklore - functors. A functor is defined as an object to be invoked or called as if it were an ordinary function, usually with the same syntax, which is exactly what a Proc is.

On Wikipedia, a closure is defined as a function that refers to free variables in its lexical context. From the example and the previous definitions, it is obvious that Ruby Procs can also act as closures. Note how closely it maps to the Ruby definition blocks of code that have been bound to a set of local variables.

More on Procs

Procs in Ruby are first-class objects, since they can be created during runtime, stored in data structures, passed as arguments to other functions and returned as the value of other functions. Actually, the gen_times example demonstrates all of these criteria, except for “passed as arguments to other functions”. This one can be presented as follows:

  def foo (a, b)
      a.call(b)
  end
  
  putser = Proc.new {|x| puts x}
  foo(putser, 34)

There is also a shorthand notation for creating Procs - the Kernel method lambda [2] (we’ll come to methods shortly, but for now assume that a Kernel method is something akin to a global function, which can be called from anywhere in the code). Using lambda the Proc object creation from the previous example can be rewritten as:

  putser = lambda {|x| puts x}

Actually, there are two slight differences between lambda and Proc.new. First, argument checking. The Ruby documentation for lambda states: Equivalent to Proc.new, except the resulting Proc objects check the number of parameters passed when called. Here is an example to demonstrate this:

  pnew = Proc.new {|x, y| puts x + y}
  lamb = lambda {|x, y| puts x + y}

  # works fine, printing 6
  pnew.call(2, 4, 11)
  
  # throws an ArgumentError
  lamb.call(2, 4, 11)

Second, there is a difference in the way returns are handled from the Proc. A return from Proc.new returns from the enclosing method (acting just like a return from a block, more on this later):

  def try_ret_procnew
      ret = Proc.new { return "Baaam" }
      ret.call
      "This is not reached"
  end
  
  # prints "Baaam"
  puts try_ret_procnew

While return from lambda acts more conventionally, returning to its caller:

  def try_ret_lambda
      ret = lambda { return "Baaam" }
      ret.call
      "This is printed"
  end
  
  # prints "This is printed"
  puts try_ret_lambda

With this in light, I would recommend using lambda instead of Proc.new, unless the behavior of the latter is strictly required. In addition to being a whopping two characters shorter, its behavior is less surprising.

Methods

Simply put, a method is also a block of code. However, unlike Procs, methods are not bound to the local variables around them. Rather, they are bound to some object and have access to its instance variables [3]:

  class Boogy
      def initialize
          @id = 15
      end
  
      def arbo
          puts "The id is #{@id}"
      end
  end

  # initializes an instance of Boogy
  b = Boogy.new

  
  b.arbo
  # prints "The id is 15"

A useful idiom when thinking about methods is that you are sending messages to the object that the method is defined for. Given a receiver - an object that has some method defined - we send it a message, which contains the name of the method, and optionally provides the arguments that the method would receive. In the example above, calling the method arbo without any arguments, is akin to sending a message with just “arbo” as the argument.

Ruby supports the message sending idiom more directly, by including the send method in class Object (which is the parent of all objects in Ruby). So the following three lines are equivalent to the arbo method call:

  # method is called on the object, with no arguments
  b.arbo

  # method/message name is given as a string
  b.send("arbo")
  
  # method/message name is given as a symbol
  b.send(:arbo)

Note that methods can also be defined in the so-called “top-level” scope, which is not inside any user-defined class. For example:

  def say (something)
      puts something
  end
  
  say "Hello"

While it seems that the method say is “free-standing”, it is not - Ruby silently tucks it into the Object class, which represents the scope of your application:

  def say (something)
      puts something
  end
  
  say "Hello"
  Object.send(:say, "Hello") # this will be the same as the above line

But this doesn’t really matter, and for all practical purposes say can be seen as an independent method. Which is, by the way, just what’s called a “function” in some languages (like C and Perl). The following Proc is, in many ways similar:

  say = lambda {|something| puts something}
  
  say.call("Hello")

  # same effect
  say["Hello"]

The [] construct is a synonym to call in the context of Proc [4]. Methods, however, are more versatile than procs and support a very important feature of Ruby, which I will present right after explaining what blocks are.

Blocks

Blocks are so closely related to Procs that it gives many newbies a headache trying to decipher how they actually differ. I will try to ease on comprehension with a (hopefully not too corny) metaphor. Blocks, as I see them, are unborn Procs. Blocks are the larval, Procs are the insects. A block does not live on its own - it prepares the code for when it will actually become alive, and only when it is bound and converted to a Proc, it starts living:

  # a naked block can't live in Ruby
  # this is a compilation error !
  {puts "hello"}
  
  # now it's alive, having been converted
  # to a Proc !
  pr = lambda {puts "hello"}

  pr.call

Is that it, is that what all the fuss is about, then ? No, not at all. The designer of Ruby, Matz saw that while passing Procs to methods (and other Procs) is nice and allows high-level functions and all kinds of fancy functional stuff, there is one common case that stands high above all other cases - passing a single block of code to a method that makes something useful out of it, for example iteration. And as a very talented designer, Matz decided that it is worthwhile to emphasize this special case, and make it both simpler and more efficient.

Passing a block to a method

No doubt that any programmer who has spent at least a couple of hours with Ruby has been shown the following examples of Ruby glory (or something very similar):

  10.times do |i|
      print "#{i} "
  end
  
  numbers = [1, 2, 5, 6, 9, 21]
  
  numbers.each do |x|
      puts "#{x} is " + (x >= 3 ? "many" : "few")
  end
  
  squares = numbers.map {|x| x * x}

(Note that do |x| ... end is equivalent to { |x| ... }.)

Such code is, in my opinion, the part of what makes Ruby the clean, readable, and wonderful language it is. What happens here behind the scenes is quite simple, or at least may be depicted in a very simple way. Perhaps Ruby may not implement it exactly the way I am going to describe it, since there are optimization considerations surely playing their role, but it is definitely close enough to the truth to serve as a metaphor for understanding.

Whenever a block is appended to a method call, Ruby automatically converts it to a Proc object but one without an explicit name. The method, however, has a way to access this Proc, by means of the yield statement. See the following example for clarification:

  def do_twice
      yield 
      yield
  end

  do_twice {puts "Hola"}

The method do_twice is defined and called with an attached block. Although the method did not explicitly ask for the block in its arguments list, the yield can call the block. This can be implemented in a more explicit way using a Proc argument:

  def do_twice(what)
      what.call
      what.call
  end

  do_twice lambda {puts "Hola"}

This is equivalent to the previous example but using blocks with yield is cleaner and better optimized since only one block is passed to the method. Using the Proc approach, any amount of code blocks can be passed:

  def do_twice(what1, what2, what3)
      2.times do
          what1.call
          what2.call
          what3.call
      end
  end

  do_twice(   lambda {print "Hola, "},
              lambda {print "querido "},
              lambda {print "amigo\n"})

This is important to note that many people frown at passing blocks and prefer explicit Procs instead. Their rationale is that a block argument is implicit and one has to look through the whole code of the method to see if there are any calls to yield there, while a Proc is explicit and can be immediately spotted in the argument list. While this is simply a matter of taste, understanding both approaches is vital.

The ampersand (&)

The ampersand operator can be used to explicitly convert between blocks and Procs in a couple of cases. It is worthy to understand how these work.

Remember how I said that although an attached block is converted to a Proc under the hood, it is not accessible as a Proc from inside the method ? Well, if an ampersand is prepended to the last argument in the argument list of a method, the block attached to this method is converted to a Proc object and gets assigned to that last argument:

  def contrived(a, &f)
      # the block can be accessed through f
      f.call(a)
      
      # but yield also works !
      yield(a)
  end
  
  # this works
  contrived(25) {|x| puts x}
  
  # this raises ArgumentError, because &f 
  # isn't really an argument - it's only there 
  # to convert a block
  contrived(25, lambda {|x| puts x})

Another (IMHO far more efficacious) use of the ampersand is the other-way conversion - converting a Proc into a block. This is very useful because many of Ruby’s great built-ins, and especially the iterators, expect to receive a block as an argument, and sometimes it’s much more convenient to pass them a Proc. The following example is taken right from the excellent “Programming Ruby” book by the pragmatic programmers:

  print "(t)imes or (p)lus: "
  times = gets
  print "number: "
  number = Integer(gets)
  if times =~ /^t/
      calc = lambda {|n| n*number }
  else
      calc = lambda {|n| n+number }
  end
  puts((1..10).collect(&calc).join(", "))

The collect method expects a block, but in this case it is very convenient to provide it with a Proc, since the Proc is constructed using knowledge gained from the user. The ampersand preceding calc makes sure that the Proc object calc is turned into a code block and is passed to collect as an attached block.

The ampersand also allows the implementation of a very common idiom among Ruby programmers: passing method names into iterators. Assume that I want to convert all words in an Array to upper case. I could do it like this:

  words = %w(Jane, aara, multiko)
  upcase_words = words.map {|x| x.upcase}
  
  p upcase_words

This is nice, and it works, but I feel it’s a little bit too verbose. The upcase method itself should be given to map, without the need for a separate block and the apparently superfluous x argument. Fortunately, as we saw before, Ruby supports the idiom of sending messages to objects, and methods can be referred to by their names, which are implemented as Ruby Symbols. For example:

  p "Erik".send(:upcase)

This, quite literally, says send the message/method upcase to the object “Erik”. This feature can be utilized to implement the map {|x| x.upcase} in an elegant manner, and we’re going to use the ampersand for this! As I said, when the ampersand is prepended to some Proc in a method call, it converts the Proc to a block. But what if we prepend it not to a Proc, but to another object? Then, Ruby’s implicit type conversion rules kick in, and the to_proc method is called on the object to try and make a Proc out of it. We can use this to implement to_proc for Symbol and achieve what we want:

  class Symbol
      
      # A generalized conversion of a method name
      # to a proc that runs this method.
      #
      def to_proc
          lambda {|x, *args| x.send(self, *args)}
      end
      
  end
  
  # Voilà !
  words = %w(Jane, aara, multiko)
  upcase_words = words.map(&:upcase)

Dynamic methods

You can define a method on "just one object" in Ruby.

  a = 'b'
  def a.some_method
    'within a singleton method just for a'
  end
  >> a.some_method
  => 'within a singleton method just for a'

Or you can use define_(singleton_)method, which preserves the scope around the definition, as well.

  a = 'b'
  a.define_singleton_method(:some_method) {
    'within a block method'
  }
  a.some_method

Special methods

Ruby has a number of special methods that are called by the interpreter. For example:

  class Chameleon
    alias __inspect__ inspect
    def method_missing(method, *arg)
      if (method.to_s)[0..2] == "to_"
        @identity = __inspect__.sub("Chameleon", method.to_s.sub('to_','').capitalize)
        def inspect
          @identity
        end
        self
      else
        super #method_missing overrides the default Kernel.method_missing
              #pass on anything we weren't looking for so the Chameleon stays unnoticed and uneaten ;)
      end
    end
  end
  mrlizard = Chameleon.new
  mrlizard.to_rock

This does something silly but method_missing is an important part of meta-programming in Ruby. In Ruby on Rails it is used extensively to create methods dynamically.

Another special method is initialize that ruby calls whenever a class instance is created, but that belongs in the next chapter: Classes.

Conclusion

Ruby doesn’t really have functions. Rather, it has two slightly different concepts - methods and Procs (which are, as we have seen, simply what other languages call function objects, or functors). Both are blocks of code - methods are bound to Objects, and Procs are bound to the local variables in scope. Their uses are quite different.

Methods are the cornerstone of object-oriented programming, and since Ruby is a pure-OO language (everything is an object), methods are inherent to the nature of Ruby. Methods are the actions Ruby objects do - the messages they receive, if you prefer the message sending idiom.

Procs make powerful functional programming paradigms possible, turning code into a first-class object of Ruby allowing to implement high-order functions. They are very close kin to Lisp’s lambda forms (there’s little doubt about the origin of Ruby’s Proc constructor lambda)

The construct of a block may at first be confusing, but it turns out to be quite simple. A block is, as my metaphor goes, an unborn Proc - it is a Proc in an intermediate state, not bound to anything yet. I think that the simplest way to think about blocks in Ruby, without losing any comprehension, would be to think that blocks are really a form of Procs, and not a separate concept. The only time when we have to think of blocks as slightly different from Procs is the special case when they are passed as the last argument to a method which may then access them using yield.

That’s about it, I guess. I know for sure that the research I conducted for this article cleared many misunderstandings I had about the concepts presented here. I hope others will learn from it as well. If you see anything you don’t agree with - from glaring errors to small inaccuracies, feel free to amend the book.

Notes

[1] It seems that in the pure, theoretical interpretation what Ruby has isn’t first-class functions per se. However, as this article demonstrates, Ruby is perfectly capable of fulfilling most of the requirements for first-class functions, namely that functions can be created during the execution of a program, stored in data structures, passed as arguments to other functions, and returned as the values of other functions.

[2] lambda has a synonym - proc, which is considered ‘mildly deprecated’ (mainly because proc and Proc.new are slightly different, which is confusing). In other words, just use lambda.

[3] These are ‘instance methods’. Ruby also supports ‘class methods’, and ‘class variables’, but that is not what this article is about.

[4] Or more accurately, call and [] both refer to the same method of class Proc. Yes, Proc objects themselves have methods!

Syntax - Classes

Classes are the basic templates from which object instances are created. A class is made up of a collection of variables representing internal state and methods providing behaviours that operate on that state.

Class Definition

Classes are defined in Ruby using the class keyword followed by a name. The name must begin with a capital letter and by convention names that contain more than one word are run together with each word capitalized and no separating characters (CamelCase). The class definition may contain method, class variable, and instance variable declarations as well as calls to methods that execute in the class context at read time, such as attr_accessor. The class declaration is terminated by the end keyword.

Example:

  class MyClass
    def some_method
    end
  end

Instance Variables

Instance variables are created for each class instance and are accessible only within that instance. They are accessed using the @ operator. Outside of the class definition, the value of an instance variable can only be read or modified via that instance's public methods.

Example:

 
  class MyClass
    @one = 1
    def do_something
      @one = 2
    end
    def output
      puts @one
    end
  end
  instance = MyClass.new
  instance.output
  instance.do_something
  instance.output

Surprisingly, this outputs:

 nil
 2


This happens (nil in the first output line) because @one defined below class MyClass is an instance variable belonging to the class object (note this is not the same as a class variable and could not be referred to as @@one), whereas @one defined inside the do_something method is an instance variable belonging to instances of MyClass. They are two distinct variables and the first is accessible only in a class method.

Accessor Methods

As noted in the previous section, an instance variable can only be directly accessed or modified within an instance method definition. If you want to provide access to it from outside, you need to define public accessor methods, for example

  class MyClass
    def initialize
      @foo = 28
    end

    def foo
      return @foo
    end

    def foo=(value)
      @foo = value
    end
  end

  instance = MyClass.new
  puts instance.foo
  instance.foo = 496
  puts instance.foo

Note that ruby provides a bit of syntactic sugar to make it look like you are getting and setting a variable directly; under the hood

  a = instance.foo
  instance.foo = b

are calls to the foo and foo= methods

  a = instance.foo()
  instance.foo=(b)

Since this is such a common use case, there is also a convenience method to autogenerate these getters and setters:

  class MyClass
    attr_accessor :foo

    def initialize
      @foo = 28
    end
  end

  instance = MyClass.new
  puts instance.foo
  instance.foo = 496
  puts instance.foo

does the same thing as the above program. The attr_accessor method is run at read time, when ruby is constructing the class object, and it generates the foo and foo= methods.

However, there is no requirement for the accessor methods to simply transparently access the instance variable. For example, we could ensure that all values are rounded before being stored in foo:

  class MyClass
    def initialize
      @foo = 28
    end

    def foo
      return @foo
    end

    def foo=(value)
      @foo = value.round
    end
  end

  instance = MyClass.new
  puts instance.foo
  instance.foo = 496.2
  puts instance.foo #=> 496

Class Variables

Class variables are accessed using the @@ operator. These variables are associated with the class hierarchy rather than any object instance of the class and are the same across all object instances. (These are similar to class "static" variables in Java or C++).

Example:

  class MyClass
    @@value = 1
    def add_one
      @@value= @@value + 1
    end
    
    def value
      @@value
    end
  end
  instanceOne = MyClass.new
  instanceTwo = MyClass.new
  puts instanceOne.value
  instanceOne.add_one
  puts instanceOne.value
  puts instanceTwo.value

Outputs:

 1
 2
 2

Class Instance Variables

Classes can have instance variables. This gives each class a variable that is not shared by other classes in the inheritance chain.

  class Employee
    class << self; attr_accessor :instances; end
    def store
      self.class.instances ||= []
      self.class.instances << self
    end
    def initialize name
      @name = name
    end
  end
  class Overhead < Employee; end
  class Programmer < Employee; end
  Overhead.new('Martin').store
  Overhead.new('Roy').store
  Programmer.new('Erik').store
  puts Overhead.instances.size    # => 2
  puts Programmer.instances.size  # => 1

For more details, see MF Bliki: ClassInstanceVariables

Class Methods

Class methods are declared the same way as normal methods, except that they are prefixed by self, or the class name, followed by a period. These methods are executed at the Class level and may be called without an object instance. They cannot access instance variables but do have access to class variables.

Example:

  class MyClass
    def self.some_method
      puts 'something'
    end
  end
  MyClass.some_method

Outputs:

 something

Instantiation

An object instance is created from a class through the process called instantiation. In Ruby this takes place through the Class method new.

Example:

  anObject = MyClass.new(parameters)

This function sets up the object in memory and then delegates control to the initialize function of the class if it is present. Parameters passed to the new function are passed into the initialize function.

  class MyClass
    def initialize(parameters)
    end
  end

Declaring Visibility

By default, all methods in Ruby classes are public - accessible by anyone. There are, nonetheless, only two exceptions for this rule: the global methods defined under the Object class, and the initialize method for any class. Both of them are implicitly private.

If desired, the access for methods can be restricted by public, private, protected object methods.

It is interesting that these are not actually keywords, but actual methods that operate on the class, dynamically altering the visibility of the methods, and as a result, these 'keywords' influence the visibility of all following declarations until a new visibility is set or the end of the declaration-body is reached.

Private

Simple example:

  class Example
    def methodA
    end
    
    private # all following methods in this class are private, so are inaccessible to outside objects
    
    def methodP
    end
  end

If private is invoked without arguments, it sets access to private for all subsequent methods. It can also be invoked with named arguments.

Named private method example:

  class Example
    def methodA
    end
    
    def methodP
    end
    
    private :methodP
  end

Here private was invoked with an argument, and set the visibility of methodP to private.

Note that class methods---those declared using def ClassName.method_name---must be set to private using the private_class_method function.

A common usage of private_class_method is to make the constructor method new inaccessible, forcing access to an object through some getter function. A typical Singleton implementation is an obvious example:

  class SingletonLike
    private_class_method :new
    
    def SingletonLike.create(*args, &block)
      @@inst = new(*args, &block) unless @@inst
      return @@inst
    end
  end

The following is another popular way to write the same declaration:

  class SingletonLike
    private_class_method :new
    
    def SingletonLike.create(*args, &block)
      @@inst ||= new(*args, &block)
    end
  end

Whereas private means "private to this class" in C++, it means "private to this instance" in Ruby. This means that C++ allows access to the private methods of any object in a given class by any code which is also in that class. In Ruby, on the other hand, private methods are local to the instantiated objects to which they belong.

The fact that private methods cannot be called with explicit receivers is illustrated by the following code.

  class AccessPrivate
    def a
    end
    private :a # a is private method
        
    def accessing_private
      a              # sure! 
      self.a         # nope! private methods cannot be called with an explicit receiver, even if that receiver is "self"
      other_object.a # nope, a is private, so you can't get it (but if it was protected, you could!)
    end
  end

Here, other_object is the "receiver" that method a is invoked on. For private methods, it does not work. However, that is what "protected" visibility will allow.

Public

The default visibility level for a method is "public", and this visibility level can be manually specified using the public method.

I am not sure why this is specified - maybe for completeness, maybe so that you could dynamically make some method private at some point, and later - public.

In Ruby, visibility is completely dynamic. You can change method visibility at runtime!

Protected

Now, “protected” deserves more discussion. Those of you coming from Java or C++ have learned that in those languages, if a method is “private”, its visibility is restricted to the declaring class, and if the method is “protected”, it will be accessible to children of the class (classes that inherit from parent) or other classes in that package.

In Ruby, “private” visibility is similar to what “protected” is in Java. Private methods in Ruby are accessible from children. You can’t have truly private methods in Ruby; you can’t completely hide a method.

The difference between protected and private is subtle. If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object---it is never possible to access another object instance's private methods directly, even if the object is of the same class as the caller. For protected methods, they are accessible from objects of the same class (or children).

So, from within an object "a1" (an instance of Class A), you can call private methods only for instance of "a1" (self). And you cannot call private methods of object "a2" (that also is of class A) - they are private to a2. But you can call protected methods of object "a2" since objects a1 and a2 are both of class A.

Ruby FAQ gives following example - implementing an operator that compares one internal variable with a variable from the same class (for purposes of comparing the objects):

  def <=>(other)
    self.age <=> other.age
  end

If age is private, this method will not work, because other.age is not accessible. If "age" is protected, this will work fine, because self and other are of same class, and can access each other's protected methods.

To think of this, protected actually reminds me of the "internal" accessibility modifier in C# or "default" accessibility in Java (when no accessibility keword is set on method or variable): method is accessible just as "public", but only for classes inside the same package.

Instance Variables

Note that object instance variables are not really private, you just can't see them. To access an instance variable, you need to create a getter and setter.

Like this (no, don't do this by hand! See below):

  class GotAccessor
    def initialize(size)
      @size = size
    end
    
    def size
      @size
    end
    def size=(val)
      @size = val
    end
  end
  
  # you could access the @size variable as
  # a = GotAccessor.new(5)
  # x = a.size 
  # a.size = y

Luckily, we have special functions to do just that: attr_accessor, attr_reader, attr_writer. attr_accessor will give you get/set functionality, reader will give only getter and writer will give only setter.

Now reduced to:

  class GotAccessor
    def initialize(size)
      @size = size
    end
    
    attr_accessor :size
  end
  
  # attr_accessor generates variable @size accessor methods automatically:
  # a = GotAccessor.new(5)
  # x = a.size 
  # a.size = y

Inheritance

The super keyword only accessing the direct parents method. There is a workaround though.

A class can inherit functionality and variables from a superclass, sometimes referred to as a parent class or base class. Ruby does not support multiple inheritance and so a class in Ruby can have only one superclass. The syntax is as follows:

  
  class ParentClass
    def a_method
      puts 'b'
    end
  end
  
  class SomeClass < ParentClass  # < means inherit (or "extends" if you are from Java background)
    def another_method
      puts 'a'
    end
  end
  
  instance = SomeClass.new
  instance.another_method
  instance.a_method

Outputs:

  a
  b

All non-private variables and methods are inherited by the child class from the superclass.

If your class overrides a method from parent class (superclass), you still can access the parent's method by using 'super' keyword.

  class ParentClass
    def a_method
      puts 'b'
    end
  end
  
  class SomeClass < ParentClass  
    def a_method
      super
      puts 'a'
    end
  end
  
  instance = SomeClass.new
  instance.a_method

Outputs:

  b
  a

(because a_method also did invoke the method from parent class).

If you have a deep inheritance line, and still want to access some parent class (superclass) methods directly, you can't. super only gets you a direct parent's method. But there is a workaround! When inheriting from a class, you can alias parent class method to a different name. Then you can access methods by alias.

  class X
    def foo
      "hello"
    end
  end
  
  class Y < X
    alias xFoo foo
    def foo
      xFoo + "y"
    end
  end

  class Z < Y
    def foo
      xFoo + "z"
    end
  end
  
  puts X.new.foo
  puts Y.new.foo
  puts Z.new.foo

Outputs

 hello
 helloy
 helloz

Mixing in Modules

First, you need to read up on modules Ruby modules. Modules are a way of grouping together some functions and variables and classes, somewhat like classes, but more like namespaces. So a module is not really a class. You can't instantiate a Module, and a module cannot use Self to refer to itself. Modules can have module methods (as classes can have class methods) and instances methods as well.

We can, though, include the module into a class. Mix it in, so to speak.

module A
  def a1
    puts 'a1 is called'
  end
end

module B
  def b1
    puts 'b1 is called'
  end
end

module C
  def c1
    puts 'c1 is called'
  end
end

class Test
  include A
  include B
  include C

  def display
    puts 'Modules are included'
  end
end

object=Test.new
object.display
object.a1
object.b1
object.c1

Outputs:

Modules are included
a1 is called
b1 is called
c1 is called

Modules can be mixed into classes in a few different ways. Before diving into this section, it's important to understand the way that objects resolve messages into method names.

Include

module A
  def a1
    puts "a1 from module"
  end
end

class Test
  include A

  def a1
    puts "a1 from class"
  end
end

test = Test.new
test.a1

Outputs:

a1 from class

When using include the methods provided by the class are searched before the methods provided by the module. This means that the method from the class will be found first and executed.

Prepend

module A
  def a1
    puts "a1 from module"
  end
end

class Test
  prepend A

  def a1
    puts "a1 from class"
  end
end

test = Test.new
test.a1

Outputs:

a1 from module

When using prepend the methods provided by the module are searched before the methods provided by the class. This means that the method from the prepended module will be found first and executed.

The code shows Multiple Inheritance using modules.

Ruby Class Meta-Model

In keeping with the Ruby principle that everything is an object, classes are themselves instances of the class Class. They are stored in constants under the scope of the module in which they are declared. A call to a method on an object instance is delegated to a variable inside the object that contains a reference to the class of that object. The method implementation exists on the Class instance object itself. Class methods are implemented on meta-classes that are linked to the existing class instance objects in the same way that those classes instances are linked to them. These meta-classes are hidden from most Ruby functions.

Syntax - Hooks

Ruby provides callbacks, to, for example, know when a new method is defined (later) in a class.

Here is a list of known callbacks.

const_missing

class Object
  def self.const_missing c
    p 'missing const was', c
  end
end

or more

class Object
  class << self
    alias :const_missing_old :const_missing
    def const_missing c
      p 'const missing is', c
      const_missing_old c
    end
  end
end

See also some rdoc documentation on the various keywords.

References

Built-In Functions

By default many methods are available. You can see the available ones by running methods in an irb session, ex:

>> class A; end
>> A.instance_methods

[:nil?, :===, :=~, :!~, :eql?, :class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :define_singleton_method, :hash, :__id__, :object_id, :to_enum, :enum_for, :gem, :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__]

You can see where most of those methods are defined by inspecting the object hierarchy:

>> A.ancestors
=> [A, Object, Kernel, BasicObject]

1.9 introduced a few more has __method__ (the current method name), as well as require_relative, which requires a file relative to the dir of the current file.

To see where each methods was defined, you can run something like:

>> A.instance_methods.map{|m| [m,  A.instance_method(m).owner] }
=> [[:nil?, Kernel], ...

Predefined Variables

Ruby's predefined (built-in) variables affect the behavior of the entire program, so their use in libraries isn't recommended.

The values in most predefined variables can be accessed by alternative means.

$!

  • The last exception object raised. The exception object can also be accessed using => in rescue clause.


$@

  • The stack backtrace for the last exception raised. The stack backtrace information can retrieved by Exception#backtrace method of the last exception.


$/

  • The input record separator (newline by default). gets, readline, etc., take their input record separator as optional argument.


$\

  • The output record separator (nil by default).


$,

  • The output separator between the arguments to print and Array#join (nil by default). You can specify separator explicitly to Array#join.


$;

  • The default separator for split (nil by default). You can specify separator explicitly for String#split.


$.

  • The number of the last line read from the current input file. Equivalent to ARGF.lineno.


$<

  • Synonym for ARGF.


$>

  • Synonym for $defout.


$0

  • The name of the current Ruby program being executed.


$$

  • The process.pid of the current Ruby program being executed.


$?

  • The exit status of the last process terminated.


$:

  • Synonym for $LOAD_PATH.


$DEBUG

  • True if the -d or --debug command-line option is specified.


$defout

  • The destination output for print and printf ($stdout by default).


$F

  • The variable that receives the output from split when -a is specified. This variable is set if the -a command-line option is specified along with the -p or -n option.


$FILENAME

  • The name of the file currently being read from ARGF. Equivalent to ARGF.filename.


$LOAD_PATH

  • An array holding the directories to be searched when loading files with the load and require methods.


$SAFE

  • The security level.
    0   No checks are performed on externally supplied (tainted) data. (default)

    1   Potentially dangerous operations using tainted data are forbidden.

    2   Potentially dangerous operations on processes and files are forbidden.

    3   All newly created objects are considered tainted.

    4   Modification of global data is forbidden.

$stdin

  • Standard input (STDIN by default).


$stdout

  • Standard output (STDOUT by default).


$stderr

  • Standard error (STDERR by default).


$VERBOSE

  • True if the -v, -w, or --verbose command-line option is specified.


$- x

  • The value of interpreter option -x (x=0, a, d, F, i, K, l, p, v).


The following are local variables:

$_

  • The last string read by gets or readline in the current scope.


$~

  • MatchData relating to the last match. Regex#match method returns the last match information.


The following variables hold values that change in accordance with the current value of $~ and can't receive assignment:

$ n ($1, $2, $3...)

  • The string matched in the nth group of the last pattern match. Equivalent to m[n], where m is a MatchData object.


$&

  • The string matched in the last pattern match. Equivalent to m[0], where m is a MatchData object.


$`

  • The string preceding the match in the last pattern match. Equivalent to m.pre_match, where m is a MatchData object.


$'

  • The string following the match in the last pattern match. Equivalent to m.post_match, where m is a MatchData object.


$+

  • The string corresponding to the last successfully matched group in the last pattern match.


Predefined Classes

In ruby even the base types (also predefined classes) can be hacked.[5] In the following example, 5 is an immediate,[6] a literal, an object, and an instance of Fixnum.

class Fixnum

	alias other_s to_s
	def to_s()
		a = self + 5
		return a.other_s
	end

end


a = 5
puts a.class  ## prints Fixnum
puts a        ## prints 10 (adds 5 once)
puts 0        ## prints 5  (adds 5 once)
puts 5        ## prints 10 (adds 5 once)
puts 10 + 0   ## prints 15 (adds 5 once)

b = 5+5
puts b        ## puts 15 (adds 5 once)

Footnotes

  1. ^ Which means the 4 VALUE bytes are not a reference but the value itself. All 5 have the same object id (which could also be achieved in other ways).
  2. ^ Might not always work as you would like, the base types don't have a constructor (def initialize), and can't have singleton methods. There are some other minor exceptions.

Objects

Object is the base class of all other classes created in Ruby. It provides the basic set of functions available to all classes, and each function can be explicitly overridden by the user.

This class provides a number of useful methods for all of the classes in Ruby.

Object inherits from BasicObject which allows creating alternate object hierarchies. Methods on object are available to all classes unless explicitly overridden.

In Ruby, everything is an Object including classes and modules. Object and BasicObject are the most low-level class.

Constants

ARGF

ARGF is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN.

ARGV

ARGV contains the command line arguments used to run ruby with the first value containing the name of the executable.

DATA

DATA is a File that contains the data section of the executed file. To create a data section use __END__:

ENV

ENV is a Hash-like accessor for environment variables.

STDERR

Holds the original stderr

STDIN

Holds the original stdin

STDOUT

Holds the original stdout

Array

Class Methods

 Method: [ ]	 Signature: Array[ [anObject]* ] -> anArray

Creates a new array whose elements are given between [ and ].

 Array.[]( 1, 2, 3 ) -> [1,2,3]
 Array[ 1, 2, 3 ] -> [1,2,3]
 [1,2,3] -> [1,2,3]

Class

Ruby Programming/Reference/Objects/Class

Comparable

Ruby Programming/Reference/Objects/Comparable

Encoding

Encoding is basically a new concept introduced in Ruby 1.9

Strings now have "some bytes" and "some encoding" associated with them.

In 1.8, all strings were just "some bytes" (so basically treated as what BINARY/ASCII-8BIT encoding is in 1.9). You had to use helper libraries to use any m18n style stuff.

By default, when you open a file and read from it, it will read as strings with an encoding set to

Encoding.default_external (which you can change).

This also means that it double checks the strings "a bit" for correctness on their way in.

In windows, it also has to do conversion from "\r\n" to "\n" which means that when you read a file in non-binary mode in windows, it has to first analyze the incoming string for correctness, then (second pass) convert its line endings, so it is a bit slower.

Recommend 1.9.2 for windows users loading large files, as it isn't quite as slow. Or read them as binary (File.binread or a=File.open('name', 'rb').

here is one good tutorial. here is another. [7] is another.

Enumerable

Enumerable

Enumerator appears in Ruby as Enumerable::Enumerator in 1.8.x and (just) Enumerator in 1.9.x.

Forms of Enumerator

There are several different ways in which an Enumerator can be used:

  • As a proxy for “each”
  • As a source of values from a block
  • As an external iterator

1. As a proxy for “each”

This is the first way of using Enumerator, introduced in ruby 1.8. It solves the following problem: Enumerable methods like #map and #select call #each on your object, but what if you want to iterate using some other method such as #each_byte or #each_with_index?

An Enumerator is a simple proxy object which takes a call to #each and redirects it to a different method on the underlying object.

require 'enumerator'   # needed in ruby <= 1.8.6 only

src = "hello"
puts src.enum_for(:each_byte).map { |b| "%02x" % b }.join(" ")

The call to ‘enum_for’ (or equivalently ‘to_enum’) creates the Enumerator proxy. It is a shorthand for the following:

newsrc = Enumerable::Enumerator.new(src, :each_byte)
puts newsrc.map { |b| "%02x" % b }.join(" ")

In ruby 1.9, Enumerable::Enumerator has changed to just Enumerator

2. As a source of values from a block

In ruby 1.9, Enumerator.new can instead take a block which is executed when #each is called, and directly yields the values.

block =  Enumerator.new {|g| g.yield 1; g.yield 2; g.yield 3}

block.each do |item|
  puts item
end

“g << 1” is an alternative syntax for “g.yield 1”

No fancy language features such as Fiber or Continuation are used, and this form of Enumerator is easily retro-fitted to ruby 1.8

It is quite similar to creating your own object which yields values:

block = Object.new
def block.each
  yield 1; yield 2; yield 3
end

block.each do |item|
  puts item
end

However it also lays the groundwork for “lazy” evaluation of enumerables, described later.

3. As an external iterator

ruby 1.9 also allows you turn an Enumerator around so that it becomes a “pull” source of values, sometimes known as “external iteration”. Look carefully at the difference between this and the previous example:

block =  Enumerator.new {|g| g.yield 1; g.yield 2; g.yield 3}

while item = block.next
  puts item
end

The flow of control switches back and forth, and the first time you call #next a Fiber is created which holds the state between calls. Therefore it is less efficient that iterating directly using #each.

When you call #next and there are no more values, a StopIteration exception is thrown. This is silently caught by the while loop. StopIteration is a subclass of IndexError which is a subclass of StandardError.

The nearest equivalent feature in ruby 1.8 is Generator, which was implemented using Continuations.

require 'generator'
block = Generator.new {|g| g.yield 1; g.yield 2; g.yield 3}

while block.next?
  puts block.next
end

Lazy evaluation

In an Enumerator with a block, the target being yielded to is passed as an explicit parameter. This makes it possible to set up a chain of method calls so that each value is passed left-to-right along the whole chain, rather than building up intermediate arrays of values at each step.

The basic pattern is an Enumerator with a block which processes input values and yields (zero or more) output values for each one.

  Enumerator.new do |y|
    source.each do |input|     # filter INPUT
      ...
      y.yield output           # filter OUTPUT
    end
  end

So let’s wrap this in a convenience method:

class Enumerator
  def defer(&blk)
    self.class.new do |y|
      each do |*input|
        blk.call(y, *input)
      end
    end
  end
end

This new method ‘defer’ can be used as a ‘lazy’ form of both select and map. Rather than building an array of values and returning that array at the end, it immediately yields each value. This means you start getting the answers sooner, and it will work with huge or even infinite lists. Example:

res = (1..1_000_000_000).to_enum.
  defer { |out,inp| out.yield inp if inp % 2 == 0 }.   # like select
  defer { |out,inp| out.yield inp+100 }.               # like map
  take(10)
p res

Although we start with a list of a billion items, at the end we only use the first 10 values generated, so we stop iterating once this has been done.

You can get the same capability in ruby 1.8 using the facets library. For convenience it also provides a Denumberable module with lazy versions of familiar Enumerable methods such as map, select and reject.

Methods which return Enumerators

From 1.8.7 on, many Enumerable methods will return an Enumerator if not given a block.

>> a = ["foo","bar","baz"]
=> ["foo", "bar", "baz"]
>> b = a.each_with_index
=> #<Enumerable::Enumerator:0xb7d7cadc>
>> b.each { |args| p args }
["foo", 0]
["bar", 1]
["baz", 2]
=> ["foo", "bar", "baz"]
>> 

This means that usually you don’t need to call enum_for explicitly. The very first example on this page reduces to just:

src = "hello"
puts src.each_byte.map { |b| "%02x" % b }.join(" ")

This can lead to somewhat odd behaviour for non-map like methods - when you call #each on the object later, you have to provide it with the “right sort” of block.

=> ["foo", "bar", "baz"]
>> b = a.select
=> #<Enumerable::Enumerator:0xb7d6cfb0>
>> b.each { |arg| arg < "c" }
=> ["bar", "baz"]
>> 

More Enumerator readings

each_with_index

each_with_index calls its block with the item and its index.

array = ['Superman','Batman','The Hulk']

array.each_with_index do |item,index|
  puts "#{index} -> #{item}"
 end

# will print
# 0 -> Superman
# 1 -> Batman
# 2 -> The Hulk

find_all

find_all returns only those items for which the called block is not false

range = 1 .. 10

# find the even numbers

array = range.find_all { |item| item % 2 == 0 }

# returns [2,4,6,8,10]
array = ['Superman','Batman','Catwoman','Wonder Woman']

array = array.find_all { |item| item =~ /woman/ }

# returns ['Catwoman','Wonder Woman']

Exception

Exception is the superclass for exceptions

Instance Methods

backtrace

  • Returns the backtrace information (from where exception occurred) as an array of strings.


exception

  • Returns a clone of the exception object. This method is used by raise method.


message

  • Returns the exception message.

FalseClass

The only instance of FalseClass is false.

Methods:

false & other - Logical AND, without short circuit behavior
false | other - Logical OR, without short circuit behavior
false ^ other - Exclusive Or (XOR)

IO - Fiber

A Fiber is a unit of concurrency (basically a manually controlled thread). It is a new construct in 1.9

1.8 basically used green threads similar, to fibers, but would pre-empt them, which 1.9 does not do.

See its description.

Several useful things have been built using fibers, like neverblock, the revactor gem, et al.

IO

The IO class is basically an abstract class that provides methods to use on streams (for example, open files, or open sockets).

Basically, you can call several different things on it.

Encoding

Note that with 1.9, each call will return you a String with an encoding set, based on either how the connection was established, ex:

a = File.new('some filename', 'rb:ASCII-8BIT') # strings from this will be read in as ASCII-8BIT
b = File.new('some filename', 'r') # strings from this will be read in as whatever the Encoding.default_external is
# you can change what the encoding will be
a.set_encoding "UTF-8" # from now on it will read in UTF-8

gets

gets reads exactly one line, or up to the end of the file/stream (and includes the trailing newline, if one was given). A blocking call.

recv

recv(1024) reads up to at most 1024 bytes and returns your the String. A blocking call. Reads "" if a socket has been closed gracefully from the other end. It also has non blocking companions.

read

read reads up to the end of the file or up to when the socket is closed. Returns any number of bytes. Blocking. For information on how to avoid blocking, see Socket.

IO - File

File

The file class is typically used for opening and closing files, as well as a few methods like deleting them and stat'ing them.

If you want to manipulate a file, not open it, also check out the Pathname class, as well as the FileUtils class.

To create a directory you'll need to use the Dir.mkdir method.

File#chmod

Here's how to do the equivalent of "chmod u+x filename"

File.class_eval do
   def self.addmod(flags, filename)
     themode=stat(filename).mode | flags
     chmod(themode, filename)
   end
end

Although there's no error checking and the return value could probably be something better (like themode).

So after defining that, your 'u+w' would be: @File.addmod(0200, 'filename')@ from http://www.ruby-forum.com/topic/196999#new

File#grep

This is actually Enumerable#grep, and I believe it just works piece-wise, like File.each_line{|l|yield l if l=~ /whatever/ }

File.join

This is useful for combining objects that aren't (or might not be) strings into a path. See here.

IO - File::Stat

File::Stat

A File::Stat object is one that contains a file's status information.

Example:

stat = File.stat('/etc') # a File::Stat object
if stat.directory?
  puts '/etc is a directory last modified at ' + stat.mtime.to_s
end

You can also get a stat object for open file descriptors.

a = File.open('some file')
a.stat # File::Stat object

IO - GC

GC

Ruby does automatic Garbage Collection.


Tuning the GC

MRI's GC is a "full mark and sweep" and is run whenever it runs out of memory slots (i.e. before adding more memory, it will sweep the existing to see if it can free up some first--if not it adds more memory). It also is triggered after GC_MALLOC_LIMIT of bytes has been allocated by extensions. Unfortunately this causes a traversal of all memory, which is typically slow. See a good description.

The GC is known to typically take 10% of cpu, but if you have a large RAM load, it could take much more.

GC can be tuned at "compile time" (MRI/KRI's < 1.9) http://blog.evanweaver.com/articles/2009/04/09/ruby-gc-tuning or can be tuned by using environment variables (REE, MRI/KRI's >= 1.9).

Some tips:

You can set the compiler variable GC_MALLOC_LIMIT to be a very high value, which causes your program to use more RAM but to traverse it much less frequently. Good for large apps, like rails.

You can use jruby/rubinius which use more sophisticated GC's.

You can use "native" libraries which store the values away so that Ruby doesn't have to keep track of them and collect them. Examples: "NArray" gem and "google_hash" gem.

To turn it off: @GC.disable@

To force it to run once: @GC.start@

Conservative

Ruby's (MRI's) GC is mark and sweep, which means it is conservative. To accomplish this, it traverses the stack, looking for any section of memory which "looks" like a reference to an existing ruby object, and marks them as live. This can lead to false positives, even when there are no references to an object remaining.

This problem is especially bad in the 1.8.x series, when they don't have the MBARI patches applied (most don't, REE does). This is because, when you use threads, it actually allocates a full copy of the stack to each thread, and as the threads are run, their stack is copied to the "real" stack, and they can pick up ghost references that belong to other threads, and also because the 1.8 MRI interpreter contains huge switch statements, which leave a lot of memory on the stack untouched, so it can continue to contain references to "ghost" references in error.

This all means that if you call a GC.start, it's not *guaranteed* to collect anything.

Some hints around this:

  • If you call your code from within a method, and come *out* of that method, it might collect it more readily.
  • You can do something of your own GC by using an ensure block, like
 a = SomeClass.new
begin
 ...
ensure
 a.cleanup
end
  • If you write a "whole lot more" memory it might clear the stack of its old references.

Tunning Jruby's GC.

"here":http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/27550 is an example of how to tune Jruby's GC. The G1GC is theoretically a "never pause" GC, though in reality most of them are pretty good at being speedy. For long running apps you'll probably want to run in server mode (--server), for increased performance, though decreased startup time.

Rubinius is also said to have a better GC.

How to avoid performance penalty

Since MRI's GC is basically O(N) as it grows, you get a performance penalty when GC's occur and you are using a lot of RAM in your app (and MRI almost never gives its RAM back to the system). Workarounds:

  1. use less RAM by allocating fewer objects
  2. do work in a forked "child process" which returns back the values desired. The child will die, freeing up its memory.
  3. use Jruby et al (jruby has an excellent GC which doesn't slow things down much, even with larger apps).
  4. use a gem that allows for native types, like NArray or the RubyGoogle Hash.
  5. use REE instead of 1.8.6 (since it incorporates the MBARI patches which make the GC much more efficient).
  6. use 1.9.x instead of 1.8.6 (since it uses true threads there is much less reference ghosting on the stack, thus making the GC more efficient).
  7. set your app to restart periodically (passenger can do this).
  8. create multiple apps, one designed to be large and slow, the others nimble (run your GC intensive all in the large one).
  9. call GC.start yourself, or mix it with GC.disable
  10. use memprof gem to see where the leaks are occurring (or the dike gem or the like).

IO - GC - Profiler

This is a class in 1.9 MRI

GC::Profiler.enable
# ... stuff
GC::Profiler.report # outputs to stdout
# or
report = GC::Profiler.result # a is set to a verbose ascii string
GC::Profiler.disable # stop it
</code>

Note also the existence of GC.count (number of times it has run).

Note that you can get a more report by setting a compiler flag <pre>GC_PROFILE_MORE_DETAIL=1

Note that the outputs "invoke Time(sec)" is actually the sum of user cpu time until that invoke occurred—i.e. a sleep 1 will result it is increasing by 0, but a busy loop for one second will result in it increasing by 1.

Marshal

Marshal

The Marshal class is used for serializing and de-serializing objects to disk:

ex

serialized = Marshal.dump(['an', 'array', 'of', 'strings'])
unserialized = Marshal.restore(serialized)

With 1.9, each dump also includes an encoding, so you *must* use Marshal's stream read feature if you wish to read it from an IO object, like a file.


a = File.open("serialized_data", "w")
a.write Marshal.dump(33)
b = File.open("serialized_data", "r")
unserialized = Marshal.restore(b)
b.close

Method

Ruby Programming/Reference/Objects/Method

Math

Ruby Programming/Reference/Objects/Math

Module

Ruby Programming/Reference/Objects/Module

Module - Class

Ruby Programming/Reference/Objects/Module/Class

NilClass

Ruby Programming/Reference/Objects/NilClass

Numeric

Numeric provides common behavior of numbers. Numeric is an abstract class, so it should not be instantiated.
Included Modules:

Comparable

Instance Methods:
+ n

    Returns n.

- n

    Returns n negated.

n + num
n - num
n * num
n / num

    Performs arithmetic operations: addition, subtraction, multiplication, and division.

n % num

    Returns the modulus of n.

n ** num

    Exponentiation.

n.abs

    Returns the absolute value of n.

n.ceil

    Returns the smallest integer greater than or equal to n.

n.coerce( num)

Returns an array containing num and n both possibly converted to a type that allows them to be operated on mutually. Used in automatic type conversion in numeric operators.

n.divmod( num)

    Returns an array containing the quotient and modulus from dividing n by num.

n.floor

Returns the largest integer less than or equal to n.
    1.2.floor            #=> 1
    2.1.floor            #=> 2
    (-1.2).floor         #=> -2
    (-2.1).floor         #=> -3

n.integer?

    Returns true if n is an integer.

n.modulo( num)

    Returns the modulus obtained by dividing n by num and rounding the quotient with floor. Equivalent to n.divmod(num)[1].

n.nonzero?

    Returns n if it isn't zero, otherwise nil.

n.remainder( num)

Returns the remainder obtained by dividing n by num and removing decimals from the quotient. The result and n always have same sign.
    (13.modulo(4))         #=>  1
    (13.modulo(-4))        #=> -3
    ((-13).modulo(4))      #=>  3
    ((-13).modulo(-4))     #=> -1
    (13.remainder(4))      #=>  1
    (13.remainder(-4))     #=>  1
    ((-13).remainder(4))   #=> -1
    (-13).remainder(-4))   #=> -1

n.round

   Returns n rounded to the nearest integer.
    1.2.round              #=> 1
    2.5.round              #=> 3
    (-1.2).round           #=> -1
    (-2.5).round           #=> -3

n.truncate

   Returns n as an integer with decimals removed.
    1.2.truncate           #=> 1
    2.1.truncate           #=> 2
    (-1.2).truncate        #=> -1
    (-2.1).truncate        #=> -2

n.zero?

    Returns zero if n is 0.

Numeric - Integer

Integer provides common behavior of integers (Fixnum and Bignum). Integer is an abstract class, so you should not instantiate this class.

Inherited Class: Numeric Included Module: Precision

Class Methods:

Integer::induced_from(numeric)

   Returns the result of converting numeric into an integer.

Instance Methods:

Bitwise operations: AND, OR, XOR, and inversion.

~i
i & int
i | int
i ^ int
i << int
i >> int

   Bitwise left shift and right shift.

i[n]

   Returns the value of the nth bit from the least significant bit, which is i[0].
   5[0]      # => 1
   5[1]      # => 0
   5[2]      # => 1

i.chr

   Returns a string containing the character for the character code i.
   65.chr    # => "A"
   ?a.chr    # => "a"

i.downto( min) {| i| ...}

   Invokes the block, decrementing each time from i to min.
   3.downto(1) {|i|
     puts i
   }
   # prints:
   #  3
   #  2
   #  1  

i.next
i.succ

   Returns the next integer following i. Equivalent to i + 1.

i.size

   Returns the number of bytes in the machine representation of i.

i.step( upto, step) {| i| ...}

   Iterates the block from i to upto, incrementing by step each time.
   10.step(5, -2) {|i|
     puts i
   }
   # prints:
   #  10
   #  8
   #  6  

i.succ

   See i.next

i.times {| i| ...}

   Iterates the block i times.
   3.times {|i|
     puts i
   }
   # prints:
   #  0
   #  1
   #  2

i.to_f

   Converts i into a floating point number. Float conversion may lose precision information.
   1234567891234567.to_f   # => 1.234567891e+15

i.to_int

   Returns i itself. Every object that has to_int method is treated as if it's an integer.

i.upto( max) {| i| ...}

   Invokes the block, incrementing each time from i to max.
   1.upto(3) {|i|
     puts i
   }
   # prints:
   #  1  
   #  2
   #  3

Numeric - Integer - Bignum

Ruby Programming/Reference/Objects/Numeric/Integer/Bignum

Numeric - Integer - Fixnum

Ruby Programming/Reference/Objects/Numeric/Integer/Fixnum

Numeric - Float

Ruby Programming/Reference/Objects/Numeric/Float

Range

Ruby Programming/Reference/Objects/Range

Regexp

Regexp Regular Expressions

Class Regexp holds a regular expression, used to match a pattern of strings.

Regular expressions can be created using /your_regex_here/ or by using the constructor "new".

>> /a regex/
>> /a case insensitive regex/i

or use the new constructor with constants, like

>> Regexp.new('a regex')
>> Regexp.new('a regex', MULTILINE)

To see all available creation options, please see the regex rdoc.

oniguruma

Starting with 1.9, ruby has a new Regular Expression engine (oniguruma), which is slightly faster and more powerful, as well as encoding aware/friendly. To see a good explanation of how it works, please see its rdoc.

Simplifying regexes

Strategy: name them, then combine them.

float = /[\d]+\.[\d]+/
complex = /[+-]#{float}\.#{float}/

Helper websites

"rubular":http://rubular.com lets you test your regexps online

Alternative Regular Expression Libraries

Some other wrappers exist:

PCRE Boost Regex

RubyVM

RubyVM is (as noted) very VM dependent. Currently it is defined only for 1.9.x MRI.

RubyVM::InstructionSequence.disassemble

Available on 1.9 only, this is basically a wrapper for yarv.

>> class A; def go; end; end
>> b = A.new.method(:go)
=> #
>> print RubyVM::InstructionSequence.disassemble b
== disasm: =======================
0000 trace 8 ( 1)
0002 putnil
0003 trace 16 ( 1)
0005 leave

I believe those trace methods represent calls to any Kernel#set_trace_func (or the C sibling to that ruby method).

Also note that with 1.9.2 you can pass in a proc.

String

String Class

Methods:

crypt(salt). Returns an encoded string using crypt(3). salt is a string with minimal length 2. If salt starts with "$1$", MD5 encryption is used, based on up to eight characters following "$1$". Otherwise, DES is used, based on the first two characters of salt.

Struct

Struct

A structure (Struct) is a:

  • data container, convenient way to bundle a number of attributes together without having to write an explicit class.
  • named collection of data (set of variables) representing a single idea or object.

Inside a 'structure' there is a list of fields - example:

  • Contact: first name, last name, phone, email, birthday.
  • Address: street, city, state, region, postal code, GPS location/coordinates.

Structures are similar to arrays in that they contain multiple data. However, instead of an Index to each piece of data, we have a variable "name". Using the above example:

  • structure (collection of data) = Contact
  • first field in structure 'Contact' is 'first name'

Struct can be used without any additional require statement.

Creating a structure

In Ruby Struct.new takes a set of field names as arguments and returns a new Class.

Newtype = Struct.new(:data1, :data2)
n = Newtype.new  # => <struct Newtype data1=nil, data2=nil>

Class Struct has a method new like other classes. But that method does not return an instance of Struct but rather a class which is a subclass of class Struct. Example:

pnt = Struct.new(:x, :y)    # => #<Class:0x143ce50>
pnt.ancestors #=> [#<Class:0x143d6f0>, Struct, Enumerable, Object, Kernel, BasicObject]

Arguments to Struct.new are names of fields that the generated class will have. These names must be provided as Symbols.

  1. approach / method 1
Struct.new("Point", :x, :y) #=> Struct::Point
origin = Struct::Point.new(0,0)  # #<struct Struct::Point x=0, y=0>
  1. approach / method 2
Structure_example = Struct.new(:filed1, :field2, :field3)
se = Structure_example.new("abc", "xyz", 123)    => #<struct Structure_example filed1="abc", field2="xyz", field3=123>

Struct::new returns a new Class object, which can then be used to create specific instances of the new structure. The number of actual parameters must be less than or equal to the number of attributes defined for this class; unset parameters default to nil. Passing too many parameters will raise an ArgumentError.

Changing structure values

se[:field3] = 456

Printing structure values and members

p se    => #<struct Structure_example filed1="abc", field2="xyz", field3=456>
p se.values    => ["abc", "xyz", 456]
p se.members   => [:field1, :field2, :field3]

Comparing structures

Customer = Struct.new(:name, :address)
joe1   = Customer.new("Joe", "adr1")
joe2 = Customer.new("Joe", "adr1")
jane  = Customer.new("Jane", "adr2")
joe1 == joe2      #=> true
joe1.eql?(joe2)   #=> true
joe1.equal?(joe2) #=> false
joe1 == jane      #=> false
print joe1[:name], joe1["name"], joe1[0] # same result in each case  -   => "Joe"

Please see the rdoc for Struct. Add any further examples/tutorials here.

Struct - Struct::Tms

Ruby Programming/Reference/Objects/Struct/Struct::Tms

Symbol

A Ruby symbol is the internal representation of a name. You construct the symbol for a name by preceding the name with a colon. A particular name will always generate the same symbol, regardless of how that name is used within the program.

:Object
:myVariable

Other languages call this process "interning," and call symbols "atoms."

Time

class Tuesdays
	attr_accessor :time, :place

	def initialize(time, place)
		@time = time
		@place = place
	end
end

feb12 = Tuesdays.new("8:00", "Rice U.")


As for the object, it is clever let me give you some advice though. Firstly, you don't ever want to store a date or time as a string. This is always a mistake. -- though for learning purposes it works out, as in your example. In real life, simply not so. Lastly, you created a class called Tuesdays without specifying what would make it different from a class called Wednesday; that is to say the purpose is nebulous: there is nothing special about Tuesdays to a computer. If you have to use comments to differentiate Tuesdays from Wednesdays you typically fail.

class Event
	def initialize( place, time=Time.new )
		@place = place

		case time.class.to_s
			when "Array"
				@time = Time.gm( *time )
			when "Time"
				@time = time
			else
				throw "invalid time type"
		end
	end

	attr_accessor :time, :place

end

## Event at 5:00PM 2-2-2009  CST
funStart = Event.new( "evan-hodgson day", [0,0,17,2,2,2009,2,nil,false,"CST"] )

## Event now, (see time=Time.new -- the default in constructor)
rightNow = Event.new( "NOW!" );

## You can compaire Event#time to any Time object!!
if Time.new > funStart.time
	puts "We're there"
else
	puts "Not yet"
end

## Because the constructor takes two forms of time, you can do
## Event.new( "Right now", Time.gm(stuff here) )

Thread

Thread

The Thread class in Ruby is a wrapper/helper for manipulating threads (starting them, checking for status, storing thread local variables).

Here is a good tutorial.

Note that with MRI 1.8, Ruby used "green threads" (pseudo threads--really single threaded). With 1.9, MRI uses "native threads with a global interpeter lock" so "typically single threaded". Jruby uses true concurrent threads. IronRuby uses true concurrent threads. Rubinius has threading currently like MRI 1.9. See here for a good background.

Because 1.8 uses green threads this means that, for windows, any "C" call (like gets, puts, etc.) will block all other threads until it returns. The scheduler can only switch from thread to thread when it is running ruby code. However, you can run sub processes in a thread and it will work, and you can run select and it will still be able to switch among threads. For Linux this means that you can select on $stdin and thus not block for input. For windows, though, you're really stuck. Any keyboard input will block all other threads. With 1.9 this isn't as much of a problem because of the use of native threads (the thread doing the IO call releases its hold on the GIL until the IO call returns). You can use Jruby[1] for a non blocking 1.8.

With 1.9 you can get "around" the global thread lock by wrapping a C call in rb_thread_blocking_region (this will basically allow that thread to "go off and do its thing" while the other ruby threads still operate, one at a time. When the method returns, it will enter ruby land again and be one of the "globally locked" (one at a time) threads).

Thread local variables

If you want to start a thread with a specific parameter that is unique to that thread, you could use Thread.current

Thread.new { 
  puts Thread.current # unique!
}

Or you can start it with a parameter, like

th = Thread.new(33) {|parameter|
  thread_unique_parameter = parameter
}

This avoids concurrency issues when starting threads, for example

# BROKEN
for x in [1,2,3] do
 Thread.new {
   puts x # probably always outputs 3 because x's value changes due to the outside scope
 }
end


Joining on multiple threads

For this one, use the ThreadsWait class.

require 'thwait'
ThreadsWait.join_all(th1, th2, th3) do |th_that_just_exited| # could also call it like join_all([th1, th2, ...])
  puts 'thread just exited', th_that_just_exited
end
# at this point they will all be done

Controlling Concurrency

See the Mutex class for how to control interaction between threads.

TrueClass

The only instance of TrueClass is true.

Methods:

true & other - Logical AND, without short circuit behavior
true | other - Logical OR, without short circuit behavior
true ^ other - Logical exclusive Or (XOR)
  1. http://betterlogic.com/roger/?p=2930