This posts is an introduction to Ruby and aggregates information I have learned from Codeacademy and Programming the World Wide Web and Agile Developement with Rails
Please visit here for a full list of documentation and sources on the ruby language. Another interesting resource is the Ruby’s User Guide, originally written by Yukhiro Matsumoto.
Table of Contents
1 - Origins and Uses of Ruby
2 - Naming Conventions
3 - Scalars
4 - Input and Output
5 - Control Statements
6 - Code Blocks and Iterators
7 - Procs and Lambdas
8 - Control Statements
9 - Fundamentals of Arrays
10 - Hashes
11 - Methods
12 - Sorting
13 - Pattern Matching
14 - Classes
15 - Modules
Origins and Uses of Ruby
Ruby was created in Japan by Yuki “matz” Matsumoto and was publicly released in 1995. Ruby blended parts of his favorite languages (Perl, Smalltalk, Eiffel, Ada, and Lisp) to form a new language that balanced functional programming with imperative programming.[1] Ruby has achieved mass acceptance especially with the quick growth of Rails, the web application framework created by 37signals
One interesting aspect about Ruby is that everything in Ruby is an object meaning that there are instance variables with methods. Recall that in other languages such as C, primitive data types (like integers and characters) are not objects.
1.http://www.ruby-lang.org/en/about/
Everything in Ruby is an object.
Naming Conventions
Local variables, method parameters, and method names should all start with a lower case letter or underscore: box, water_bottle, g6. Instance variables should begin with an “at”@ sign, such as @id, @telephone_number The convention is to use underscores to separate words in a multiword method or variable name water_bottle as opposed to waterBottle.
Class names, module names, and constants muststart with an uppercase letter. By convention they use capitalization, rather than underscores, to distinguish the start of words within the name. Class names look like Object, PurcharseOrder, and LineItem. This naming convention is also known as upper camel case, since the shape of the lettering looks like the humps of camel.
Rails uses symbols to identify things. In particular, symbols are used when naming method parameters and lookingthings up in hashes Symbols are prefixed with colons : like :action or :id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
By convention class names, modules names and constants use capitalization to distinguish the start of words within the name. This is known as upper camelcase
because of its shape.
Scalars
Ruby has three categories of datatypes - scalars,arrays and hashes. There are two categories of scalar types numerics and character strings. Recall that everything in Ruby is an object.
Numeric Literals
All numeric data types in Ruby are descendants of the Numeric class. The immediate child classes of Numeric are Float and Integer. The Integer class has two child classes Fixnum and Bignum.
An integer literal that fits into the range of a machine word, which is often 32 bits, is a Fixnum object (minus 1 bit). If the integer exceeds the size of the the Fixnum object then it is coereced into a Bignum object. There is no length limitation(other than the computer’s memory size) on integer literals.
Underscore characters can appear embedded in integer literals, which helps readability.
1 2 3 4 5 |
|
A numeric literal that has either an embedded decimal point or a following exponent is a Float object and uses the machines double precision floating point architecture. A decimal point must be both preceded and followed by at least one digit so .35 is not valid.You must use 0.35.
A decimal point must be both preceded and followed by at least one digit.
String Literals
All string literals are String. There are two categories of string literals, single quoted and double quoted. Single quoted literals cannot include characters(other than single quote characters) specified with escape characters. You can specify a single quote delimiter by preceding the delimiter with a %q. If the new delimiter is a parantheses, brace, bracket, or a point bracket, the corresponding closing element must be used.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Double quoted strings differ from single quoted strings in two ways: 1. They can include special characters in escape sequences 2. The values of variables names can be interpolated into a string. With string interpolation a block of code between #{ } is evaluated and then converted into a string.
With string interpolation a block of code between #{ } is evaluated and then converted into a string.
Finally a different delimiter can be used by preceding the delimiter with a %Q.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Numeric Operators
Most of the operatoirs in Ruby are similar to those in other common languages like + for addition, - for subtraction, * for multiplication, / for division.
Note however that Ruby does not support increment(++) and decrement(–) operators. Note that ** is the exponentiation operator.
1 2 3 4 |
|
Operators can also serves as methods. * can be used for repetition and + can be used for string concatenation.
1 2 3 4 5 |
|
Ruby does not support increment and decrement operators.
String Methods
The + symbol and << symbol are used to concatenate strings.
1 2 3 4 |
|
There are many String methods in Ruby.
Ruby method names can end with an exclamation mark(a bang or mutator method) or a question mark(a predicate method). A bang method changes the object in place. A predicate method indicates that a method is boolean: returns true or false.
A bang method is a method name ending with a ! and changes the the object in place.
1 2 3 4 5 6 7 8 9 10 11 |
|
A few String methods are summarized below.
capitalize Convert first letter to uppercase and the rest to lowercase
chop Removes the last character
chomp removes a new line fro mthe right end, if there is one
upcase converts all of the letters in the object to uppercase
downcase converts all of the letters
strip Removes the spaces on both ends
lstrip Removes the spaces on the left end
rstrip Removes the spaces on the right end
reverse Reverse the characters of the string
swapcase Converts all uppercase letters to lowercase and all lowercase letters to uppercase
Strings can also be accessed by an index where 0 is the first position. If a negative index is used, the index starts at the back where the last character is -1. Strings can also be index like [index,length].
1 2 3 4 5 6 7 8 9 10 |
|
Input and Output
Sometimes you may want to work with Ruby on the command line. One way is to run irb on the command line to start the Interactive Ruby Shell and then experimenting with Ruby in the console. You can execute a script by running ruby scriptname The -c flag can be used to check syntax. For a full set of flags run man ruby You can also execute a script by putting #!/usr/bin/env ruby at the top of your script and running your script like so ./scriptname If you use this method make sure that your script is executable by running chmod +x. Generally ruby scripts end with the extension .rb
Output
print is used to output a string. puts behaves like print but adds a newline to the end of output.
1 2 3 4 5 |
|
puts behaves like print but adds a newline to the end of output
Input
gets is used to retrieve a line of input from the keyboard. The parsed input is a string, and you can use string methods to filter the string. Use methods such as to_i or to_f to convert the input into an integer or float respectively.
1 2 3 4 |
|
Control Statements
Control Statements are used to control execution flow of a program.
Control Expressions
Control Expressions are logical expressions used to for control statments. A relational operator has two operands and an operator Relational Operator
== equals
!= not equals
< less than
> greater than
<= less than or equal to
>= greater than or equal to
<=> Comparator: for a <=> b returns 1 if a > b , -1 if a < b, and 0 if a == b This operator is also very help for sorting.
eql? returns true if parameter and reciever object have same type and value.
equal? returns true if parameter is the same as the reciever object. Effectly checks for same references.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Operator Precedence and associativity
Operator precendence specifies the order in which operations should be carried out. The following operators are listed in precedence from greatest to least (in descending order). Operators on the same line have the same precedence. Associativity tells you how to evaluate operations if two or more operators have the same precendence either start evaluating from the left or right. If operators are nonassociative that means that these operators cannot associative with themselves.
1 2 3 4 |
|
1 2 3 |
|
** Right
1 2 3 4 |
|
!, unary + and - Right
Here is a pretty interesting article on how to define your own unary operator
1 2 3 4 |
|
*, /, % Left
+, - Left
& Left
> , <, >= , <= Nonassociative
==, !=, <=> Nonassociative
&& Left
|| Left
=, +=, -=, *=, **=, /=, %=, &=, &&=, ||= Right
not Right
or, and Left
and and or are control-flow modifiers like if and unless
More about using and vs &&
Selection statements
Selection statements are used for conditional branching of execution.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
The case construct is the equivalent of a switch statement in other programming languages.
The then keyword following the when clauses can be replaced with a newline.
Loop Statements
Loop of statements repeatedly executed until a terminiting condition.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
… and .. are range operators for exclusive and inclusive ranges.
next is the equivalent of a continue statement in other programming languages. The program continues to the next iteration of the loop.
Although if statements are fairly common in Ruby Applications, looping constructs are rarely used. Block and iterators often take their place.
In Ruby, looping constructs are rarely used. Instead, block and iterators take their place.
Code Blocks and Iterators
Code Blocks are groups of code between do … end or curly braces {}. By convention do…end is used for multiline blocks where as {} is used for single line blocks. do/end vs curly braces
Iterators are methods used to invoke blocks repeatedly. Note that blocks can accept parameters that are delimited like so |parameter|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
collect is an iterator that applies the block on each element of the array. It creates a new array containing the values returned by the block. If you used the bang method it modifies the array in place.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Methods can transfer control to a block and back again. This is can be done using the yield method, which invokes the block with an optional parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Methods can transfer control to a block and back again. This is known as the yield method, which invokes the block with an optional parameter.
Procs and Lambdas
TODO
Proc
Procs are full-fledged objects, so they have all the powers and abilities of objects. (Blocks do not.)
Unlike blocks, procs can be called over and over without rewriting them. This prevents you from having to retype the contents of your block every time you need to execute a particular bit of code.
http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/ http://stackoverflow.com/questions/1435743/why-does-explicit-return-make-a-difference-in-a-proc http://ablogaboutcode.com/2012/01/04/the-ampersand-operator-in-ruby/
lambda
First, a lambda checks the number of arguments passed to it, while a proc does not. This means that a lambda will throw an error if you pass it the wrong number of arguments, whereas a proc will ignore unexpected arguments and assign nil to any that are missing.
Second, when a lambda returns, it passes control back to the calling method; when a proc returns, it does so immediately, without going back to the calling method.
Fundamentals of Arrays
An array is a series of elements. If you have arrays of arrays this is known as a multi-dimensional array. Array elements are indexed by integers with the first element being 0.
Ruby arrays differs from more traditional langauges such as C,C++, and Java because the lenght of an array is dynamic. They can shrinkand grown during program execution. If you’ve worked with C++, this is the same behaviior as a vector.
Generally arrays must store homogenous elements (elements of the same type). However Ruby arrays store heterogenous elements or a mix of elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
for-in
One method to loop over an array is to use the for-in statement.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Arrays have an assortment of methods. Some common methods are demoed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
Arrays can also be treated as sets The & operator is used for set intersection, -, for set difference, and |, for set union
1 2 3 4 5 6 7 8 |
|
Hashes
Arrays are indexed by integers. There is another key, value collection called a hash where an object is reference by another object known as a symbol. If you’re coming from a background in JavaScript, PHP, you maybe used to acessing hashes using strings.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Here is a good description of why symbols are used as hash keys in Ruby
“Using symbols not only saves time when doing comparisons, but also saves memory, because they are only stored once.
Symbols in Ruby are basically “immutable strings” . That means that they can not be changed, and it implies that the same symbol when referenced many times throughout your source code, is always stored as the same entity, e.g. has the same object id.
Strings on the other hand are mutable, they can be changed anytime. This implies that Ruby needs to store each string you mention throughout your source code in it’s separate entity, e.g. if you have a string “name” multiple times mentioned in your source code, Ruby needs to store these all in separate String objects, because they might change later on (that’s the nature of a Ruby string).
If you use a string as a Hash key, Ruby needs to evaluate the string and look at it’s contents (and compute a hash function on that) and compare the result against the (hashed) values of the keys which are already stored in the Hash.
If you use a symbol as a Hash key, it’s implicit that it’s immutable, so Ruby can basically just do a comparison of the (hash function of the) object-id against the (hashed) object-ids of keys which are already stored in the Hash. (much faster)
Notes:
If you do string comparisons, Ruby can compare symbols just by their object ids, without having to evaluate them. That’s much faster than comparing strings, which need to be evaluated.
If you access a hash, Ruby always applies a hash-function to compute a “hash-key” from whatever key you use. You can imagine something like an MD5-hash. And then Ruby compares those “hashed keys” against each other.”
Source: tilo’s answer from http://stackoverflow.com/questions/8189416/why-use-symbols-as-hash-keys-in-ruby
Each object is identified by an integer which can be retrieved using the method .object_id. As mentioned previously only one copy of a symbol exists at a given time, meaning that there exists only one object id for that symbol.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|