Ruby

        Quick Reference

        In-depth essential commands

        RubyDocs

Design philosophy

  1. Natural feeling language
  1. Principle of least astonishment (POLA)

When switching to Ruby from other languages, the transition should be easy and the programmer should be able to follow the same habits formed by other languages

  1. Anything can be done in almost any way

Ruby can be very personal in the style it is created in, as there are multiple methods to accomplish the same task. For example, to get a subset of a list:

myArray[1,4] == myArray[1..4] == myArray.slice(1..4)

Getting to know Ruby

  1. Including libraries or other codefiles is done with the ‘require’ statement
  2. The ‘include’ keyword is reserved for a class that needs separate module
  3. Typing is all dynamically done; an array can hold any type of contents
  4. Starting out, write high-level pseudocode and then find high-level functions. Most common tasks are already done and included in the corelibs

Hello, world!

As per standard, lets make our first ruby script ‘hello world’. Ruby files have the extension of .rb, so helloworld.rb would look something like this:

#!/usr/bin/ruby

print “Hello ”

puts “World!”

Looking at the output, we should get a simple “Hello World!\n”. This illustrates the difference between print and put in respect to the automatic insertion of a newline.

Starting out with functions

Functions are defined in ruby very similarly to python, with a dash of perl:

def MyFunc (arg1, arg2)

do something

return something

end

Arguments are simply identified as a variable name.

Variables and Scoping

Ruby has scoping rules based off of the character content of a variable name

Name Begins With            Variable Scope

$                                   A global variable

Code

$global = 10

def testFunc

            puts $global

end

testFunc()

Output

10

[a-z] or _                  A local variable

Code

notAGlobal = 10

def testFunc

            puts notAGlobal

end

testFunc()

Output

in `testFunc': undefined local variable or method `notAGlobal'

[A-Z]                       A constant

Code

MyConstant = 10

def testFunc

            puts MyConstant

            MyConstant = 30

            puts MyConstant

end

testFunc()

Output

test.rb:7: dynamic constant assignment: MyConstant = 30

@                                   An instance variable (traditional class members)

Code

class MyClass            

            def MyVariable=(value)

                    @storedVar = value

            end

            def MyVariable

                    @storedVar

            end

end

inst1 = Myclass.new

inst2 = Myclass.new

inst1.myVariable = 10

inst2.myVariable = 20

puts inst1.myVariable

Output

10

@@                                  A class variable (static across all instances / singleton)

Code

class MyClass            

            def MyVariable=(value)

                    @@storedVar = value

            end

            def MyVariable

                    @@storedVar

            end

end

inst1 = Myclass.new

inst2 = Myclass.new

inst1.myVariable = 10

inst2.myVariable = 20

puts inst1.myVariable

Output

20

Speaking of classes...

  1. Classes are trivial to define:

class MyClass

   def initialize ()

   end

   def MyMethod

            puts "Test"

   end

end

MyClassInstance = Myclass.new

  1. Inheritance can only come from one base class (no multiple inheritance)

class TestClass < BaseClass

   ...

end

  1. Ruby also allows getters and setters for class variables. In typical Ruby fashion, there are multiple ways to do this:
  1. Method 1 (wordiest, allows for custom getters / setters)

def AngleRad

@angleRad

end

def AngleRad=( value )

         @AngleRad = value

end

  1. Example of a custom getter / setter (modifying the value in transit). Here we dynamically convert the angle in radians to degrees when the getter / setter is called.

def AngleDeg

@angleRad * 180 / Math::Pi

end

def AngleDeg=( value )

         @AngleRad = value * Math::PI / 180

end

  1. Method 2 (closer, but not a one-liner yet)

attr_reader :variable

attr_writer :variable

  1. Method 3 (one-line magic!)

attr_accessor :variable

Associative Arrays: pronounced ‘dictionary’

  1. RubyDocs page
  2. Represented by the ‘hash’ class in Ruby.
  3. Initialize with either a default value to return if item is not found, or nil:

myHash = Hash.new()

myHash[‘a’]                        #=> nil

myHash = Hash.new(“Error”)

myHash[‘a’]                        #=> “Error”

  1. Setting values can be done at initialisation or on the fly:

myHash = { ‘a’ => 1, ‘b’ => 2 }

myHash[‘c’] = 3

  1. Fairly standard dictionary when compared to other languages.

Putting it all together

  1. cat.rb example
  1. First off, the #! at the top to associate it with ruby:

#!/usr/bin/ruby

  1. ARGV holds the input command line arguments so this line:

if ARGV[0] == nil

would be checking if the user supplied at least one.

  1. Begin / Rescue / Ensure is the equivalent to Try / Catch / Finally.
  1. This is useful in File I/O ensuring that a file is closed even if there are exceptions.
  1. An interesting note about this block of code:

            for line in file

            puts line

            end

At first glance some of the nuance in this is missed. The for loop iterates over lines, removing the newline constant at the end of each. This is why we use puts instead of print, as puts will put the \n back onto the line when it prints it back out.

  1. ls.rb example
  1. This example is actually remarkably simple: it opens a dir and prints out every object within it.
  2. The notation for the current dir is “.”, meaning that without input it will run on the cwd.
  3. the “Dir” class is an innate one within Ruby. Here is its RubyDoc page.
  4. Here we also see a new form of iterator:

Dir.foreach(dir) { |file| puts file }

The {brackets} declare the scope of this iterator.

  1. The open bracket must be on the same line as the close parentheses

The |abs.val| signs declare the iterator name

In english, this line could read:

        For each file in dir, print the file with a newline at the end.

  1. grep.rb example
  1. Here we get our first exposure to regular expressions in Ruby.
  2. A regular expression is defined by /slashes/ enclosing the pattern.
  3. Example:

/[a-z]+/ would match lowercase words

  1. This whole item is not a string, but a class that must be defined in one of two ways:

regex = /pattern/

regex = Regexp.new(pattern)

  1. Line 12, where it has:

regex = /#{ARGV[0]}/

is a way to make the variable ARGV[0] the regex string, instead of the variable name as the expression.

  1. The # is an escape symbol
  2. {brackets} mean to evaluate the variable enclosed
  3. The whole string of #{ARGV[0]} is replaced by the variable ARGV[0]’s value.
  1. $stdin is a pre-defined variable. See this list for more of them.
  2. Perhaps the most interesting line in the program is this one:

if line =~ regex

  1. This =~ operator translates to

regex.match(line)