Skip to content

Instantly share code, notes, and snippets.

@AndrewKiri
Last active November 2, 2017 10:35
Show Gist options
  • Save AndrewKiri/3e2727cef6e56c8dad4eae3ddd35294e to your computer and use it in GitHub Desktop.
Save AndrewKiri/3e2727cef6e56c8dad4eae3ddd35294e to your computer and use it in GitHub Desktop.
Ruby Language Docs

1. Basics


Comments

=begin
This is a comment line
it explains that the next line of code displays 
a welcome message
=end

or if you want to prevent engine from executing a piece of your ruby code

=begin
print "Welcome to Ruby Essentials!"
print "Everything you need to know about Ruby"
=end

Constants

Constants are declared by starting the name of the variable from a capital letter. The convention, though, to write the name of the variable in all upper-case letters. Unlike many programming languages, ruby does allow you to change the value that is assigned to a constant. The interpreter, however, will raise an issue warning


Getting the type of a primitive variable

To identify the type of the variable in ruby you can run the following:

y = 10
y.class #prints: Fixnum

We can also compare the variable against the type itself like so:

y.kind_of? Integer #prints: true

Mass varibale assignment

a, b, c, d = 10, 20, 30, 40

Type Conversion

You can reassing a variable different value, after which its type will change accordingly. It is somewhat desctructive way. If you want to read a value from a variable and convert it to a different type afterwards - you can use to_* (for example to_f to convert to a Fixnum type, or to_s to convert the value to a String)

y = 20
y.to_f #prints: 20.0

Variable Scopes

$ at the start of the variable name creates a it in the global scope @ - an instance variable
[a-z] - a local variable
[A-Z] - a contant variable
@@ - a class varaible
Additionally, Ruby has two more variables:
nil - which is assigned to uninitialized variables
self - which refers to the currently executing object


Detecting a scope

The best way to detect if the variable was declared in the particular scope using defined? method, which will return the scope of the variable referenced, or nil if the variable isn't defined in the current context

x = 10
defined? x #prints: "local-variable"

$y = 25
defined? $y #prints: "global-variable"

Local Variables

Local variables are local to the code construct in which they are declared. For example, a local variable declared in a method or within a loop cannot be accessed outside of that loop or method. Local variable names must begin with either an underscore or a lower case letter


Global Variables

Global variables in Ruby are accessible from anywhere in the Ruby program, regardless of where they are declared. Global variable names are prefixed with a $

Use of global variables is strongly discouraged. The problem with global variables is that, not only are they visible anywhere in the code for a program, they can also be changed from anywhere in the application. This can make tracking bugs difficult.

It is useful to know, however, that a number of pre-defined global variables are available to you as a Ruby developer to obtain information about the Ruby environment.

$@ - the location of the lates error
$0 - the name of the Ruby script file that is currently executing
$$ - the Ruby interpreter's process ID


Class Variables

A class variable is a variable that is shared amongst all instances of a class. This means that only one variable value exists for all objects instantiated from this class. This means that if one object instance changes the value of the variable, that new value will essentially change for all other object instances.

Another way of thinking of thinking of class variables is as global variables within the context of a single class.

Class variables are declared by prefixing the variable name with two @ characters (@@). Class variables must be initialized at creation time. For example:

@@total = 0

Instance Variables

Instance variables are similar to Class variables except that their values are local to specific instances of an object. For example if a class contains an instance variable called @total, if one instance of the object changes the current value of @total the change is local to only the object that made the change. Other objects of the same class have their own local copies of the variable which are independent of changes made in any other objects.

Instance variables are declared in Ruby by prefixing the variable name with a single @ sign:

@total = 10

Contant Scope

Ruby constants are values which, once assigned a value, should not be changed. I say should because Ruby differs from most programming languages in that it allows a constant value to be changed after it has been declared, although the interpreter will protest slightly with a warning message.

Constants declared within a class or module are available anywhere within the context of that class or module. Constants declared outside of a class or module are assigned global scope.


Number Classes

Ruby provides a number of built-in number classes. In this section we will explore some of the more commonly used classes.

Integer Class

The base class from which the following number classes are derived.

Fixnum Class

A Fixnum holds Integer values that can be represented in a native machine word (minus 1 bit). This effectively means that the maximum range of a Fixnum value depends on the architecture of the system on which the code is executing.

If an operation performed on a Fixnum exceeds the range defined by the system's machine word, the value is automatically converted by the interpreter to a Bignum.

Bignum Class

Bignum objects hold integers that fall outside the range of the Ruby Fixnum class. When a calculation involving Bignum objects returns a result that will fit in a Fixnum, the result is converted to Fixnum.

Float Class

The Float object represents real numbers based on the native architecture‘s double-precision floating point representation.

Rational Class

Rational implements a rational class for numbers. A rational number is a number that can be expressed as a fraction p/q where p and q are integers and q is not equal to zero. A rational number p/q is said to have numerator p and denominator q. Numbers that are not rational are called irrational numbers.


Methods

Ruby methods provide a way to organize code and promote re-use. Rather than create long sections of Ruby code, the code is instead organized into logical groups that can be called when needed and re-used without having to re-write the same code over and over. Methods are simple to use, in fact you only need to do two things with a method, declare it and call it.

def name( arg1, arg2, arg3, ... )
   .. ruby code ..
   return value
end
def saysomething()
    puts "Hello"
end

saysomething
def multiply(val1, val2 )
     result = val1 * val2
     puts result
end

multiply( 2, 10 )
multiply( 4, 20 )
multiply( 10, 40 )
multiply( 6, 7 )

Passing variable number of arguments

def displaystrings( *args )
	args.each {|string| puts string}
end
displaystrings("Red", "Green") 
# Red 
# Green

or

def displaystrings(*args)
    args.each do |string| 
        puts string
    end
end
displaystrings("Red", "Green")
# Red 
# Green

Keep in mind that the bracket syntax has a higher precedence than the do..end syntax. Consider the following two snippets of code:

1.upto 3 do |x|
  puts x
end

1.upto 3 { |x| puts x }
# SyntaxError: compile error

Reference: Curly braces vs Do

Method Aliases

Ruby allows a method to be aliased, thereby creating a copy of a method with a different name (although invoking the method with either name ultimately calls the same object). For example:

def multiply(val1, val2 )
  result = val1 * val2
  return result
end

Ranges

Ruby Ranges allow data to be represented in the form of a range (in other words a data set with start and end values and a logical sequence of values in between). The values in a range can be numbers, characters, strings or objects. In this chapter we will look at the three types of range supported by Ruby, namely sequences, conditions and intervals.


Sequence

Sequence ranges in Ruby are used to create a range of successive values - consisting of a start value, an end value and a range of values in between.

Two operators are available for creating such ranges, the inclusive two-dot (..) operator and the exclusive three-dot operator (...). The inclusive operator includes both the first and last values in the range. The exclusive range operator excludes the last value from the sequence.

1..10    # Creates a range from 1 to 10 inclusive
1...10   # Creates a range from 1 to 9

A range may be converted to an array using the Ruby to_a method.

(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

(1...10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]

As mentioned previously, ranges are not restricted to numerical values. We can also create a character based range.

('a'..'l').to_a
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]

Also, we can create ranges based on string values

('cab'..'car').to_a
=> ["cab", "cac", "cad", "cae", 
	"caf", "cag", "cah", "cai", 
	"caj", "cak", "cal", "cam", 
    "can", "cao", "cap", "caq", "car"]

Range values may also be objects. The only requirements for placing an object in a range is that the object provides a mechanism for returning the next object in the sequence via succ and it must be possible to compare the objects using the <=> operator.


Range Methods

Given the object-oriented nature of Ruby it should come as no surprise to you that a range is actually an object. As such, there are a number of methods of the Range class which can be accessed when working with a range object.

words = 'cab'..'car'

# get lowest value in range
words.min         
=> "cab"

# get highest value in range
words.max         
=> "car"

# check to see if a value exists in the range
words.include?('can') 
=> true

# reject values below a specified range value
words.reject {|subrange| subrange < 'cal'} 
=> ["cal", "cam", "can", "cao", "cap", "caq", "car"]

# iterate through each value and perform a task
words.each {|word| puts "Hello " + word} 
Hello cab
Hello cac
Hello cad
Hello cae
Hello caf
Hello cag
Hello cah
Hello cai
Hello caj
Hello cak
Hello cal
Hello cam
Hello can
Hello cao
Hello cap
Hello caq
Hello car

Ranges as Conditional Expressions

Ruby Ranges can also be used as conditional expressions in looping conditions. The range start value represents the start of the loop, which runs until the range end marker is detected.

while input = gets
 puts input + " triggered" if input =~ /start/ .. input =~ /end/
end

Range Intervals

Ranges are ideal for identifying if a value falls within a particular range. For example, we might want to know whether a number is within a certain range, or a character within a certain group of letters arranged in alphabetical order. This is achieved using the === equality operator:

# Does the number fit in the range 1 to 20
(1..20) === 15       
=> true
# Does 'm' fall between the letters 'k' and 'z' in the alphabet?
('k'..'z') === 'm'   
=> true

Ranges in case statements

score = 70

result = case score
   when 0..40: "Fail"
   when 41..60: "Pass"
   when 61..70: "Pass with Merit"
   when 71..100: "Pass with Distinction"
   else "Invalid Score"
end

puts result

Arrays

A Ruby array is an object that contains a number of items. Those items can be variables (such as String, Integer, Fixnum Hash etc) or even other objects (including other arrays to make a multidimensional array). Once you have grouped all the items into the array you can then perform tasks like sorting the array items into alphabetical or numerical order, accessing and changing the value assigned to each array item, and passing the group of items as an argument to a Ruby function.


Create an Array

Ruby provides a number of mechanisms for creating an array. Arrays essentially involve the use of the Ruby Array class. We could, therefore, create an uninitialized array using the new method of the Array class:

days_of_week = Array.new

We now have an array called days_of_week with nothing in it.

We can also initialize an array with a preset number of elements by passing through the array size as an argument to the new method:

days_of_week = Array.new(7)
=> [nil, nil, nil, nil, nil, nil, nil]

Having created an array we need to add some data to it. One way to do this is to place the same data in each element during the created process:

days_of_week = Array.new(7, "today")
=> ["today", "today", "today", "today", "today", "today", "today"]

Another option is to use the [] method of the Array class to specify the elements one by one:

days_of_week = Array[ "Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun" ]
=> ["Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun"]

This can also be abbreviated to just the array name and the square brackets:

days_of_week = [ "Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun" ]

Array Methods

Once an array exists, it can be useful to find out information about that array and its elements.

days_of_week.empty?
=> true

We can also find out the size of an array using the size method of the Array class:

days_of_week = Array.new(7)
days_of_week.size
=> 7

It is also possible find out what type of object is contained in array by using the array index value of the element we want to interrogate combined with the class method:

days_of_week = [ "Mon", 15, "Wed", 16, "Thu", 17 ]

days_of_week[0].class
=> String

days_of_week[1].class
=> Fixnum

Accessing elements of an array

The elements of an array can be accessed by referencing the index of the element in question in conjunction with the [] method. To access the first and second elements of our array therefore:

days_of_week[0]
=> "Mon"

days_of_week[1]
=> "Tues"

The Array class at method can be used to similar effect:

days_of_week.at(0)
=> "Mon"

The last element of an array may be accessed by specifying an array index of -1. For example:

days_of_week[-1]
=> "Sun"

The first and last elements may be accessed by using the first and last methods of the Array class:

days_of_week.first
=> "Mon"

days_of_week.last
=> "Sun"

Finding the index of an element

Often when working with arrays it is necessary to find out the index of a particular element. This can be achieved using the index method which returns the index of the first element to match the specified criteria. For example, to identify the index value of the "Wed" element of our days of the week array:

days_of_week.index("Wed")
=> 2

The rindex method can be used to find the last matching element in an array.


Extracting elements from Array

A subset of an array's elements may be extracted by specifying the start point and the number of elements to extract. For example, to start at element 1 and read 3 elements:

days_of_week[1, 3]
=> ["Tues", "Wed", "Thu"]

Similarly, we can specify a range

days_of_week[1..3]
=> ["Tues", "Wed", "Thu"]

Alternatively, the slice method of the Array class may be used:

 days_of_week.slice(1..3)
=> ["Tues", "Wed", "Thu"]

Combining Arrays

Arrays in Ruby can be concatenated using a number of different approaches. One option is to simply add, them together:

days1 = ["Mon", "Tue", "Wed"]
days2 = ["Thu", "Fri", "Sat", "Sun"]
days = days1 + days2
=> ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

Alternatively, the concat method may be called:

days1 = ["Mon", "Tue", "Wed"]
days2 = ["Thu", "Fri", "Sat", "Sun"]
days = days1.concat(days2)

Elements may also be appended to an existing array using the << method. For example:

days1 = ["Mon", "Tue", "Wed"]
days1 << "Thu" << "Fri" << "Sat" << "Sun"
=> ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

Intersection, Union and Difference

Ruby's support for array manipulation goes beyond that offered by many other scripting languages. One area where this is particularly true involves the ability to create new arrays based on the union, intersection and difference of two arrays. These features are provided via the following set operation symbols:
- Difference - Returns a new array that is a copy of the first array with any items that also appear in second array removed.
& Intersection - Creates a new array from two existing arrays containing only elements that are common to both arrays. Duplicates are removed.
| Union - Concatenates two arrays. Duplicates are removed.
A few examples will help to clarify these operations. Let's begin by creating two arrays:

operating_systems = ["Fedora", "SuSE", "RHEL", "Windows", "MacOS"]

linux_systems = ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "Fedora"]

Now, we can create a union of the two arrays:

operating_systems | linux_systems
=> ["Fedora", "SuSE", "RHEL", "Windows", "MacOS", "PCLinuxOS", "Ubuntu"]

As we can see from the above output, the union operation joined one array to another, but removed any duplicate array elements.
Next we can perform an intersection:

operating_systems & linux_systems
=> ["Fedora", "SuSE", "RHEL"]

This time, we only get elements that are common to both arrays.

Finally, we can try a "difference" operation:

operating_systems - linux_systems
=> ["Windows", "MacOS"]

In this case, the new array provides us with the difference between the two arrays. In other words we get a new array that contains items which are present in operating systems, but not present in linux_systems. It is important to be clear on the point that we are not simply removing duplicate entries with this operator, but rather removing items from the array specified by the left hand operand that are also present in the array specified by the right hand operand. This can be demonstrated by the fact that switching the operands gives us very different results:

linux_systems - operating_systems
=> ["PCLinuxOS", "Ubuntu"]

Identifying Unique Array Elements

The uniq method of the Array class can be used to remove duplicated elements from an array. For example:

linux_systems = ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "Fedora", "RHEL", "SuSE"]

linux_systems.uniq
=> ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "Fedora"]

Note that in this instance, the original array is unchanged by the uniq method. If you really wanted to strip out the duplicates from an array such that the array itself is altered, use the uniq! method as follows:

linux_systems
=> ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "Fedora", "RHEL", "SuSE"]

linux_systems.uniq!
=> ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "Fedora"]

linux_systems
=> ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "Fedora"]

Pushing and Popping Array Elements

An array in Ruby can be treated as a Last In First Out stack where items are pushed onto and popped off the array. This is achieved, unsurprisingly, using push and pop methods.

For example we can create an array and then push elements onto it:

colors = ["red", "green", "blue"]
=> ["red", "green", "blue"]

colors.push "indigo"
=> ["red", "green", "blue", "indigo"]

colors.push "violet"
=> ["red", "green", "blue", "indigo", "violet"]

Using the pop method we can also pop elements from the array:

colors.pop
=> "violet"

colors.pop
=> "indigo"

Array Comparison

Ruby arrays may be compared using the ==, <=> and eql? methods.

The == method returns true if two arrays contain the same number of elements and the same contents for each corresponding element.

The eql? method is similar to the == method with the exception that the values in corresponding elements are of the same value type.

Finally, the <=> method (also known as the "spaceship" method) compares two arrays and returns 0 if the arrays are equal, -1 one if the elements are less than those in the other array, and 1 if they are greater.


Modifying Arrays

A new element may be inserted into an array using the insert method. This method takes as arguments the index value of the element to be inserted, followed by the new value. For example, to insert a new color between the red and green elements:

colors = ["red", "green", "blue"]
=> ["red", "green", "blue"]

colors.insert( 1, "orange" )
=> ["red", "orange", "green", "blue"]

Any array element may be changed simply by assigning a new value using the array element index:

colors = ["red", "green", "blue"]
=> ["red", "green", "blue"]=> ["red", "yellow", "blue"]

colors[1] = "yellow"
=> "yellow"

colors
=> ["red", "yellow", "blue"]

Multiple elements can be changed by making use of a range:

colors = ["red", "green", "blue"]
=> ["red", "green", "blue"]

colors[1..2] = "orange", "pink"
=> ["orange", "pink"]

colors
=> ["red", "orange", "pink"]

Deleting Array Elements

It is not uncommon to need to delete individual elements from an array. A deletion can be performed either based on the content of an array element, or on the index position.

To delete based on an index use the delete_at method:

colors = ["red", "green", "blue"]
=> ["red", "green", "blue"]

colors.delete_at(1)
=> "green"

colors
=> ["red", "blue"]

To delete array elements based on content use the delete method:

colors = ["red", "green", "blue"]
=> ["red", "green", "blue"]

colors.delete("red")
=> "red"

colors
=> ["green", "blue"]

Sorting Arrays

Arrays are sorted in Ruby using the sort and reverse methods:

numbers = [1, 4, 6, 7, 3, 2, 5]
=> [1, 4, 6, 7, 3, 2, 5]

numbers.sort
=> [1, 2, 3, 4, 5, 6, 7]

As with the uniq method, the sorting can be applied to the actual array with the sort! method.

The order of the elements in an array can be reversed using the reverse method:

numbers = [1, 4, 6, 7, 3, 2, 5]
=> [1, 4, 6, 7, 3, 2, 5]

numbers.sort!
=> [1, 2, 3, 4, 5, 6, 7]


numbers.reverse
=> [7, 6, 5, 4, 3, 2, 1]

OOP in Ruby

Objects and Classes

An object is a self-contained piece of functionality that can be easily used, and re-used as the building blocks for a software application.

Objects consist of data variables and functions (called methods) that can be accessed and called on the object to perform tasks. These are collectively referred to as members.

Just about everything in Ruby, from numbers and strings to arrays is an object.

Much as a blueprint or architect's drawing defines what an item or a building will look like once it has been constructed, a class defines what an object will look like when it is created. It defines, for example, what the methods will do and what the member variables will be.

New classes can be created based on existing classes, a concept known as inheritance. In such a scenario the new class (known as the subclass) inherits all the features of the parent class (known as the superclass) with added features that differentiate it from the superclass. Ruby supports single inheritance in that a subclass can only inherit from a single superclass.

Other languages such as C++ support multiple inheritance where the subclass can inherit the characteristics of multiple superclasses.


Create a Class

Classes are defined using the class keyword followed by the end keyword and must be given a name by which they can be referenced. This name is a constant so must begin with a capital letter.

With these rules in mind we can begin work on our class definition:

class BankAccount
   def initialize ()
   end

   def test_method
        puts "The class is working"
   end
end

The above example defines a class named BankAccount with a single method called test_method which simply outputs a string. The initialize method is a standard Ruby class method and is the method which gets called first after an object based on this class has completed initialization. You can place any code in the initialize method and it is particularly useful for passing in arguments when the class is created.


Creating an Instance (an object from the class)

An object is created from a class using the new method. For example, to create an instance of our BankAccount class we simply perform the following:

account = BankAccount.new()

Having created the object we can call our test_method:

account.test_method
The class is working
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment