Learning Ruby
Overview about Ruby
Ruby is an interpreted rather than a compiled language. You can call it a scripting language, an object-oriented language. One of the best aspects of Ruby is its composability. Composability is the degree to which you can express logic by combining and recombining parts of a language. Ruby isn’t under committee or corporate control. It’s open source. It was writ-ten by Matz, with some help from his friends. Ruby is dynamically types language unlike java, C , C++ which are statically typed.
Is Ruby Available in your device?
To discover if Ruby is installed in your machine, go to a shell prompt on a Unix/Linux system (this won’t work on a standard Windows system) and type:
1
$ which ruby
If you get a reply like this one :/usr/local/bin/ruby
, means ruby is installed and running in your machine.
Alternatively, you can just type a command to check the version of Ruby (this works on Unix/Linux and Windows):
1
$ ruby -v
or:
1
$ ruby --version
If Ruby is installed, you should get an answer that looks like this:
ruby 1.8.6 (2007-03-13 patchlevel 0)
Running a Simple Ruby Program
Here we will be discussing on how to run a simple hello world program in Ruby.
Type the following line in a plain-text editor such as TextPad.
The file extension must be .rb
, to indicate that it is a ruby file.
Now, inside helloWorld.rb file:
1
puts "Hello World!"
You run the program by running the Ruby interpreter.
To do this, type the following at a shell or command prompt:
1
$ ruby helloWorld.rb
The output from the program is displayed by default on the screen:
Hello World!
Shebang!
You can avoid typing ruby each time on Unix/Linux systems by adding something called a shebang line (#!)
at the top of
your Ruby file.
Adding shebang
at the top of your file automatically fires up the ruby interpreter as soon as the file is executed.
NOTE: The file must be executable.
Add a shebang
line to the top of helloWorld.rb:
1
#!/usr/local/bin/ruby
OR
1
#!/usr/bin/env ruby
Now you can directly run your program from the directory where your file is located by typing in:
1
./helloWorld.rb
in your Linux Shell prompt.
You might encounter a permission denied error while running the above code. Such as:
1
-bash: ./matz.rb: Permission denied
The main reason behind this is, the file that we are trying to interpret is not executable. This can be fixed using:
1
chmod 755 matz.rb
This command makes the file executable, and thus solving our issue. To find out more about chmod, type man chmod at a shell prompt.
Some General codes with explanation
For Appending Strings
1
2
puts "hello" + "world"
puts "hello" << "World"
Displaying a String multiple times
1
2
puts "Hello, World! "* 3
3.times { print "Hello, World!" }
Both the above code will display “Hello, World” three times. But puts adds a line break after displaying each string, whereas print will print them in the same line.
1
puts "Hello" * 3 + "World"
You could also display “Hello” three times, and then append “world” along with them.
You’d get something like Hello, Hello, Hello, World!
this, as an output.
Inserting Shell command output
You can also insert some output from a shell command:
1
puts "Hey, I’m running " + `ruby --version`
The output would be something like this:
Hey, I’m running ruby 1.8.6 (2006-08-25)
Expression Substitution(Interpolation)
Intially we define a local variable containing Strings as data
1
2
person = "Sheriff!"
puts "Hello,#{person}" # => Hello, Sheriff!
Using expression substitution, you can grab an argument off the command line and add it to the output.
1
2
#!/usr/bin/env ruby
puts "Hello,#{ARGV[0]}!"
Ruby stores command-line arguments in a predefined Ruby variable called ARGV
.
ARGV[0]
refers to the first item on the command line, the 0th element in ARGV
.
Run the helloWorld.rb program to see the results:
1
$ helloWorld.rb
Hello, helloWorld!
Formatting a String
You can change the output on the fly with the %s format flag and %: “`ruby hi = "hi, %s”
puts hi % “Sheriff”
puts hi % “Roman”
puts hi % “Shristina”
You can also use % as:
ruby
puts “%s, %s!” % [ “Hello”, “Matz” ]
“
%is a method from the
Stringclass that formats a string. It is like using
sprintf`:
sprintf( "Hello, %s”, “Matz!” ) # => “Hello, Matz!”
Use printf to print the output to your display (the default standard output device).
1
2
3
sprintf( "Hello, %s", "Sheriff!" )
printf( "Hello, %s", "Sheriff!" )
The eval Method:
The eval
method evaluates a string enclosed in quotes as a Ruby statement or expression and returns the result.
It’s handy for testing.
1
eval "puts 'Hello, Matz!'" # => Hello, Matz!
1
ruby -e "print 'Hello, '" -e "puts 'Matz!'"
In the above code, we could directly run a ruby program if we do not have a file containing ruby code.
-e
is used for chaining, various ruby instructions together
Getting Input From Keyboard
1
2
3
4
#!/usr/bin/env ruby
print "Who do you want to say hello to? "
hello = gets
puts "Hello, " + hello
The gets method reads what you type and assigns it to the hello variable.
Methods
Methods can be defined with the keyword def
, followed by the method name
1
2
3
4
5
def hello
puts "Hello, Matz!"
end
hello # => Hello, Matz!
The method then can be called by calling the methods name
The block
1
2
3
def hello
yield
end
1
hello{ puts "Hello, Matz!" } # => Hello, Matz!
The yield
statement executes the block of code in braces (ie. ,{ puts “Hello,Matz!” }) associated with the method call
to hello.
The proc
You can convert a block into an object. This object is called a proc(procedure).
The nice thing about procs is that they preserve their execution environment and pack it along with them.
The lambda method is one way to create a proc object. For example:
ruby
prc = lambda { |name| puts "Hello, " + name }
`
The proc is stored in prc as the result of a call to lambda, which stores the block as an object. You can now call the proc with an argument.
The call
executes the proc with an argument=.
1
prc.call "Sheriff!" # => Hello, Sheriff!
Interactive Ruby(irb)
Interactive Ruby
, or irb
, is an interactive command-line environment for Ruby allowing you to see results (or errors)
after you enter each statement. When you install Ruby, you get irb along with it.
Start out by typing this at a prompt:
1
$ irb -v
This would return you the irb version
When you enter irb
at a shell prompt, you will get the irb prompt .
Type a Ruby statement at the prompt, and then press the Return or Enter key.
For example:
1
2
irb(main):001:0> puts "Hello, Shehriff! "
Hello, Sheriff !=> nil
The nil object indicates that, puts method returns nothing.
Prompt
PROMPT: A symbol on a display screen indicating that the computer is waiting for input. Once the computer has displayed a prompt, it waits for you to enter some information. Generally, it will wait forever, but some programs have built-in time-outs that cause the program to continue execution after it has waited a specified amount of time.
Tour on Ruby
Topics such as classes and modules, including the Object class and the Kernel module,reserved words (keywords), comment, variables, methods, and so forth will be discussed here.
Class
Ruby has classes. Class have various properties and methods associated along with them. The properties defined could be either variable or constant, and the methods are used to operate upon those properties.
Classes can inherit information from each other, but only one at a time. This allows you to reuse code.
A class is like a blueprint. With the use of a new method, this blueprint can be assigned to a variable. The variable is then called an instance or the object of a class.
In Ruby, almost every-thing is an object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Hello
def howdy
greeting = "Hello, Matz!"
puts greeting
end
end
class Goodbye < Hello
def solong
farewell = "Goodbye, Matz."
puts farewell
end
end
friendly = Goodbye.new
friendly.howdy
friendly.solong
Friendly is an object, an instance of the Goodbye class. The new method called on Goodbye comes from the Object class and creates the new instance friendly.
You can use the friendly object to call both the howdy and solong methods, because it inherently knows about them.It knows about the solong method because it is defined inside the Goodbye class, and it knows about the howdy method because Goodbye inherited it from Hello.
The Object Class and the Kernel Module:
The Object class is the Ruby base class. It is the parent of all other classes. It is always present whenever you run a Ruby program.
With Object Class comes a lot of functionality in the form of methods and constants. This functionality is inherited by all other Ruby programs automatically.
Object gives you methods like ==
and eql?
, class
, inspect
, object_id
, and to_s
.
Kernel is a Ruby module. A module is like a class, but you can’t instantiate it as an object as you can with a class. However, when you include or mix in a module in a class, you get access to all its methods within that class. You can use methods from an included module without having to implement those methods.
Object includes the Kernel module. This means that because you always get access to Object in a Ruby program, you also get all the Kernel methods, too. Some of these methods are print and puts.
A sampling of commonly used Kernel methods includes eval, exit, gets, loop, require, sleep, and sprintf.
You don’t have to prefix the Kernel methods with an object or receiver name and call the methods anywhere in any program , and they work.
Ruby’s reserved keywords:
They are the words that make statements in programs. I won’t go on details on all the types of the Ruby reserved
keywords, but some of the most commonly used Ruby reserved keywords are:
BEGIN,END,class,def,else,elsif,false,for,self
Comments
Single Line Comments: #
Multi line Comments: =begin
&& =end
Example for multiline comment:
ruby
=begin
This line is commented
This line is also commented
=end
Variables
Variables are dynamically types in Ruby, and they will have a type at runtime. Many modern programming languages, like C++ and Java, are statically type. Variables are used for storing various types of values which can be referenced by a name. For example, a variable with name x is assigned some value such as, x = 100
In case of statically typed variables, the variable is assigned a type at the time it is declared,and,because languages such as Java are also strongly typed, the variable remains that type unless it is cast into a different type, if it is possible to do so.
In case of Ruby, you don’t have to give them a type because Ruby does that for you, automatically
It’s called dynamic or duck typing.
If you observe an aquatically competent bird, and it walks like a duck, quacks like a duck, flies like a duck, and swims like a duck, it’s probably a duck.
Ruby likewise looks at a value assigned to a variable, and if it walks, quacks, flies, and swims like an integer, i.e. the value behaves in a way that is similar to an integer then Ruby assumes it to be an integer.
A method of the Object Class in Ruby kind_of
can be used to determine the type of a variable.
1
2
x.kind_of?
Integer # => true
x is also an instance of the Fixnum class
, which inherits the Integer class
.
x.class # => Fixnum Change
The value of x from an integer to a floating point with the to_f method from the Fixnum class.
x.to_f # => 100.0
Local variables:
Local variables must start with a lowercase letter or with an underscore character (_).
Example: alpha
or _beta
We can identify a local variable in Ruby is that its name is not prefixed by a special character or symbol, other than _.
When a local variable is defined inside of a method or a loop, its scope is within the method or loop where it was defined.
Instance variables:
An instance variable is prefixed by a single at sign(@). For Example:
@hello = hello
An instance variable is a variable that is referenced via an instance of a class and therefore belongs to a given object.
You can access instance variables from outside of their class only by accessor methods
Class variables:
A class variable can be seen as similar to static variables in Java as they are also shared among all instances of a class. Only one copy of a class variable exists for a given class.
In Ruby, it is prefixed by two at signs (@@) and it must be initialized before use.
For example:
@@times = 0
Global Variables
They are prefixed by a dollar sign ($). For Example:
$amount = "0.00"
Global variables are available globally to a program, inside any structure. Their scope is the whole program.
It’s hard to keep track of global variables and it is considered to use class variables or constants instead of global variable.
Even according to Martz, they must not be used, and he personally never uses them.
Constants:
A constant holds a constant value for the life of a Ruby program. Constants are variables whose names are capitalized or all uppercase.
For Example:
Matz = "Yukihiro Matsumoto"
If a constant is defined within a class or module, you can access the constant from within that class or module. On the other hand if it is defined outside either a class or module, the constant is available globally. Unlike other languages, a Ruby constant is mutable, i.e. you can change its value
Parallel Assignment
In ruby the variables can be declared, then the values, with commas:
x, y, z = 100, 200, 500
You can even assign values of different kinds, such as a string, float, and integer:
a, b, c = "cash", 1.99, 100
Strings
A string is a sequence of letters, numbers, and other characters.
In ruby a string can be created as follows:
introduction = "My name is Sheriff"
There are various ways to defining a string in Ruby, by surrounding a text around a double or a single quotation is the one of the most easiest way to do it.
you can retrieve part of a string with the [] method, using a range .Let’s grab characters 3 through 6:
introduction[3..6] # => "name"
Starting at the end of the string using negative numbers, get the second to last character through the eighth to last:
introduction[-7..-1] # => “Sheriff”
each_byte
method
You can iterate over all the characters in the string using a block that munches on every byte (8-bit sequence) in an ASCII string and generates a character (with the chr method), separating each character with a slash: For Example:
1
2
3
4
5
introduction.each_byte do |c|
print c.chr, "/"
end
# => M/y/ /n/a/m/e/ /i/s/ /S/h/e/r/i/f/f/ => "My name is Sheriff"
Regular Expression
A regular expression or regexps is a special sequence of characters that matches strings or a set of strings. They are generally used to retrieve a string or substring.
Regexps use elements (one or more characters) to instruct the regular expression engine on how to find a given string.
A combination of the special characters,enclosed by a pair of slashes (//), makes up a regular expression pattern.
Some examples of these elements are:
^ Matches the beginning of a line
$ Matches the end of a line
\w Matches a word character
[…] Matches any character in the brackets
[^…] Matches any characters not in the brackets
* Matches zero or more occurrences of the previous regexp
+ Matches one or more occurrences of the previous regexp ? Matches zero or one occurrences of the previous regexp
Here is an example of a regular expression used to match a string with the String method scan.
1
2
hamlet = "My name is Sheriff Hussain"
hamlet.scan(/\w+/) # => ["My", "name", "is", "Sheriff", "Hussain"].
This regexp matches one or more (+) word characters (\w), and places all the matches in an array.
Numbers and Operators
In Ruby even numbers are instances of classes.
For example, the number 1001, a positive integer, is an instance of the Fixnum class, which is a child class of Integer, which is a child class of Numeric.
The number 1001.0, a floating point value, is an instance of the Float class, which is also a child class of Numeric.
Various operations can be peformed on the numbers. Such as addition, substraction, division, multiplication, raise to power, modulus and other assignment operators.
Ruby also has a Math module that provides all kinds of math functions (in the form of class methods), like square root, cosine, tangent, and so forth.
Here is an example call to the class method sqrt from the Math module:
1
Math.sqrt(16)=> 4.0
Conditional Statements
Similar to other programming languages. In Ruby, the conditional statement executes a block if a condition is evaluated to be true. For example:
1
2
3
4
value = 0
if value.zero? then
puts "value is zero."
end
The zero? method returns true if the value of value is zero.
By Ruby convention, any method in Ruby that ends with a question mark returns a Boolean, either true or false.
Other conditionals include familiar ones like case and while, and less familiar ones like until and unless.
Arrays and Hashes
Array
An array is an ordered sequence of indexed values, with an index starting at zero. It is one of the most common data structures.
1
person = ["Sheriff", "Roman", "Pramod"]
The three strings are the elements of the array. The elements of an array can be of any Ruby kind, not just strings.
To access a member of an array, you must use the index number of the array element. you could use the [ ] method.
1
person[0] # => "Sheriff"
Hash
A hash is a map of keys to values. It is also a very common data structure.
Unlike an array, which indexes elements with positive integers, hashes let you choose how you will index the values with a key of your choice.
1
2
person = { "name" => "Sheriff", "address" => "Budhanilkhanta", "hobbies" => "guitar" }
The hash definition is enclosed in curly braces, whereas an array is defined in square brackets.
Each value in a hash is associated (=>) with a key. One of the ways you can access the values in a hash is by their keys.
To access the value Oregon from the hash,you could use Hash’s [ ] method.
1
person["name"] # => "Sheriff"
Using the key name returns the value Sheriff.
Note: The keys and values can be of any kind, not just strings.
Methods
Methods provide a way to gather code (statements and expressions) into one place so that you can use it conveniently and, if necessary, repeatedly.
You can define methods to do all kinds of things. In fact, most of the math operators in Ruby are actually methods.
Methods can be defined using the keyword def. And then can be called by using the method name.
On the flip side, you can undefine a method with undef.
After undefining a method, if you try to call it you get an error.
You can also define methods that have arguments, as shown here in the repeat method:
1
2
3
4
5
6
def repeat( word, times )
puts word * times
end
repeat("Hello! ", 3) # => Hello! Hello! Hello!
repeat "Good-bye! ", 4 # => Good-bye! Good-bye! Good-bye! Good-bye!
Note: You can even define method arguments without parentheses. Such as:
def repeat word,times
Because you don’t have to use parentheses, it is possible to have normal-looking math equations when you use operator methods, such as +.
Each line that follows is actually a valid call to the Fixnum + method:
For Example:
1
2
3
10 + 2 # => 12
10.+ 2 # => 12
(10).+(2) # => 12
Return Values of Methods
Methods have return values. In other languages, you can explicitly deliver a return value with a return statement.
In Ruby, the last value in a method is returned, with or without an explicit return
statement.
For Example:
1
2
3
def sum a,b
a + b
end
Invoking the method would return the result of a + b
, without having to write a return
statement explicitly.
Method Name Conventions:
If a method name ends with a question mark ?, as in zero?, then the method returns a Boolean — true
or false
value.
For example:
1
2
x = 1.0
x.zero? # =>false
If a method name ends in an exclamation point !, as in delete!, it indicates that the method is “destructive” — that is, it makes changes in place to an object rather than to a copy. It changes the object itself.
If a method name ends in an equals sign =, as in family_name=, then the method is a “setter”, i.e., one that performs an assignment or sets a variable such as an instance variable in a class.
For Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Name
def family_name=( family )
@family_name = family
end
def given_name=( given )
@given_name = given
end
end
n = Name.new
n.family_name= "Hussain" # => "Hussain"
n.given_name= "Sheriff" # => "Sheriff"
p n # => <Name:0x1d441c@family_name="Hussain", @given_name="Sheriff">
Default Arguments
You can give those arguments default values by using an equals sign followed by a value. When you call the method without arguments, the defaults are used automatically.
For example :
1
2
3
4
5
6
7
8
9
def
repeat(word="Hello! ",times=3 )
puts word * times
end
repeat # => Hello! Hello! Hello!
repeat( "Goodbye! ", 5 ) # => Goodbye! Goodbye! Goodbye! Goodbye! Goodbye.
When you call the new call to repeat without arguments, the default values for the arguments are used, but if you call repeat with arguments, the defaults are discarded and replaced by the values of the arguments.
Variable Arguments:
At times when you don’t know how many arguments a method will have, you as pass a variable number of arguments to a method just by prefixing an argument with a splat (*).
For Example:
1
2
3
4
5
6
7
8
9
def num_args(*args )
length = args.size
label = length == 1 ? " argument" : " arguments"
num = length.to_s + label + " ( " + args.inspect + " )"
end
puts num_args
puts num_args(1)
puts num_args(100, 2.5, "three")
This program uses the ternary operator (?:) to determine if the noun argument should be singular or plural.
Note: When you use this syntax for a variable number of arguments, the arguments are stored in an array, as shown by the inspect method.
Output:
1
2
3
0 arguments ( [] )
1 argument ( [1] )
3 arguments ( [100, 2.5, "three"]
Variable Arguments with Set Arguments
You can have set arguments along with variable arguments. The trick is that the variable list of arguments (the one that starts with *) always comes at the end of the argument list.
For Example:
1
2
3
4
5
def two_plus(one, two, *args )
length = args.size
label = length == 1 ? " variable argument" : " variable arguments"
num = length.to_s + label + " (" + args.inspect + ")"
end
Output:
1
2
3
0 variable arguments ([])
1 variable argument ([14.3])
3 variable arguments (["three", 70, 14.3])
The output only shows how many variable arguments you get, it ignores the regular arguments.
Aliasing Methods
Ruby has a keyword alias that creates method aliases. Aliasing means that you in effect create a copy of the method with a new method name, though both method invocations will point to the same object.
Using alias (or Module’s method alias_method) gives you a way to have access to methods that have been overridden.
For Example:
1
2
3
4
5
6
7
def greet
puts "Hello World"
end
alias another_greet greet
puts greet.object_id
puts another_greet.object_id
the object_id points to the same object.
Blocks
In most of the cases blocks are always invoked in conjunction with a method and are also referred to as a nameless function. A block in Ruby is can be seen as a code block or group of statements.
The block is also used to extract values from a data structure such as an array, hash, etc.
1
2
person = [ "Sheriff", "Roman", "Shristina" ]
You can call a block on the person array to retrieve all of its elements, one at a time, with the each method.
1
2
3
person.each do |element|
puts element
end
The name between the pipe characters (|element|) can be any name you want. The block uses it as a local variable to keep track of every element in the array, and later uses it to do something with the element.
Output:
1
2
3
Sheriff
Roman
Shritina
You can replace do/end with a pair of braces. Braces have a higher precedence than do/end. They can be used to reduce the line of codes and make them tighter.
For example:
1
person.each { |e| puts e }
Block are also used along with the yield
keyword in ruby.
For example:
Define a method called hello that only contains yield in it’s body.
1
2
3
def hello
yield
end
When calling the hello method alone, the following error can be seen in the console.
1
hello LocalJumpError:no block given
The job of yield is to execute the code block that is associated with the method. To avoid error we can use the block_given? method from Kernel.
1
2
3
4
5
6
7
def hello
if block_given?
yield
else
puts "I'm blockless!"
end
end
If there is a block given with the method call, block_given? will return true, and yield will execute the block. Otherwise, if there is no block given, it will execute the code in else.
Now, let’s call the hello method.
1
2
hello { print "Say hi to the people." } # => Say hi to the people.
hello # => I'm blockless!
When you supply it a block, hello yields the code in the block.
If a method is defined in such a way that it contains two yields, tt executes the block twice.
For example:
1
2
3
4
5
6
7
8
9
10
def hello
if block_given?
yield
yield
else
puts "I'm blockless!"
end
end
hello { print "Say hi again. " } # => Say hi again. Say hi again.
After the yield is executed, control of the program is transferred to the immediate next statement following yield.
For example:
1
2
3
4
5
6
7
8
9
10
def hello
if block_given?
yield
else
puts "Oops. No block."
end
puts "You're welcome." # executes right after yield
end
hello { print "Thank you. " } # => Thank you. You're welcome
NOTE: Blocks Are Closures: A closure is a nameless function or method. It is like a method within a method, that refers to or shares variables with the enclosing or outer method. In Ruby, the closure or block is wrapped by curly braces ({}) or do/end, and depends on the associated method (such as each) in order to work.
Procs
Prcos are known as procedures. They can be called as an object, and the block of code within them can be executed. Some of the ways of creating procs are:
- Call new on the Proc class.
- Call the lambda method from Kernel.
- Call the proc method from Kernel.
The proc and lambda methods also perform parameter checking.
For example:
1
2
3
proc_first = Proc.new { [1,2,3,4,5].each do |i| print i end; puts }
proc_second = lambda { puts "Ram: 'Hello'" }
proc_third =proc { puts "Shyam: 'Hello, how are you?'" }
The class method returns the object type of the following procs.
1
puts proc_first.class, proc_second.class, proc_third.class
Each of the objects created above are Proc objects
The above procs can be called using the call method.
For example:
1
2
3
4
# Calling all procs
proc_first.call
proc_second.call
proc_third.call
The program gives you this output as it calls each of the procs with the call method:
1
2
3
12345
Ram: 'Hello'
Shyam: 'Hello, how are you?'
Conversion of block to proc
Initially create an argument to the method that is proceeded by anampersand (&).
For Example:
1
2
3
4
5
6
7
8
9
10
11
def return_block
yield
end
def return_proc(&proc )
yield
end
return_block { puts "Got block!" }
return_proc { puts "Got block, convert to proc!" }
Here is the output:
1
2
Got block!
Got block, convert to proc!
In the return_block method,the yield statement’s purpose is to execute a block when the block is passed to a method.
return_proc has one argument, &proc.
When a method has an argument preceded by an ampersand, it will accept block and convert it to a Proc object.
With yield in the body, the method executes the block as proc, without having to bother with the Proc call method.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
def return_block
yield
end
def return_proc(&proc )
proc
end
return_block {puts "Hello World"}
sheriff = return_proc {puts "Hello Sheriff from Proc"}
puts sheriff.call
Output:
1
2
Hello World
Hello Sheriff from Proc
The block {puts "Hello Sheriff from Proc"}
is converted into proc, and the proc is returned to the variable
sheriff.
The proc is then called using the statement sheriff.call
.
Symbols:
Symbol in Ruby is basically the same thing as symbol in real world. It is used to represent or name something.
They are Ruby objects of the Symbol class that act like placeholders for identifiers and strings.
They can also be used for used for identifying a specific resource. A resource can be: a method a variable a hash key a state
They are always prefixed by a colon (:).
You can create a symbol by calling the to_sym
or intern
methods on a string.
Once a symbol is created,only one copy of the symbol is held in a single memory address, as long as the program is running.
For example:
1
2
:pending.object_id # => 1277788
:pending.object_id # => 1277788
The :pending symbol is only created once.
The main difference between them relies on the fact that a new String object is created for each called string — even if they’re identical.
For example:
1
2
'pending'.object_id # => 70324176174080
'pending'.object_id # => 70324176168090
As we can in the example above, the identical strings ‘pending’ have different object ids.
Because of this, rather than making copy after copy, Ruby keeps referring back to that single memory address. This makes Ruby programs more efficient because they don’t take up as much memory.
Exception Handling:
Java and C++ have try blocks; in Ruby, you would just use a begin block.
catch statements in Java and C++ are used where Ruby has rescue statements.
Where Java uses a finally clause, Ruby uses ensure.
Conditional Statement
The if Statement
1
2
3
if 1 == 1 then
print "True!"
end
If the condition 1 equals(==) 1 is true, then the if statement returns true, and the code block, consisting only of a print statement will execute.
Another Example:
1
2
3
4
5
x = 256
if x == 256
puts "x equals 256"
end
# => x equals 256
You can also write the if
statement in one line as:
1
2
x = 256
if x == 256 then puts "x equals 256" end
For Example:
1
2
x = 256
puts "x equals 256" if x == 256
When you change the order like this, the if is referred to as a statement modifier.
The && operator
The && operator means “and.”
1
2
3
4
5
6
pen = "copy"
pencil = "book"
if pen == "copy" && pencil == "book"
puts "This block is executed"
end
# => This block is executed
If both these statements are true, the code in the block is executed.
The || operator
|| operator is a synonym for this operator is or.
You can use || or or, if any of the statements are true, the code executes:
1
2
3
4
5
6
pen = "copy"
pencil = "notBook"
if pen == "copy" or pencil == "notBook"
puts "This block is executed"
end
# => This block is executed
Only one condition must be true, in order for the block to be executed.
Some of the other operators that are used instead of && and || are:
The not equal to
1
print"Hello" if 1!= 2
Greater than operator
1
2
amt=2.00
if amt > 1.00 then print "expensive" end
Less than operator
1
2
amt=0.5
if amt < 1.00 then print "cheap" end
Greater than or equal to operator
1
if height >= 6 then print "L or XL" end
Less than or equal to operator
1
if weight <= 100 then print "shrimpy" end
! and not reverse the meaning.
For example:
1
2
3
if !queue then
print "The queue is empty."
end
The Ternary Operator
Example:
1
noun = number == 1 ? " book" : " books"
On the basis of the value of the number variable, either “book” or “books” is assigned to the noun variable. If the number is equal to 1 then noun is assignment “book”, and if the number is anything else than 1, than the variable noun is assignment “books”.
Case Statment
The case statement is similar to the switch case statement in Java or C. It works as follows:
Example:
1
2
3
4
5
6
7
price = 100
case price
when 50 then puts "Cheap"
when 100 then puts "Reasonable"
when 150 then puts "Expensive"
end
The While Loop
A while loop executes the code it contains as long as its conditional statement remains true.
1
2
3
4
5
i=0
while i < 10
puts i
i += 1
end
Another use of while can be with begin and end.
1
2
3
4
5
i=0
begin
puts i
i += 1
end while i < 10
When you use while like this, with while at the end, the statements in the loop are evaluated once before the conditional is checked. This is like the do/while loop from C.
Note: like if, you can use while as a statement modifier, at the end of a statement.
For Example:
1
2
3
cash = 100
cash += 100.00 while cash < 1000000.00
puts cash
Break Statement
Break is used to get the control out of the loop.
1
2
3
4
5
6
i = 0
while i < 10
puts i
i += 1
break if i == 6
end
Output:
1
2
3
4
5
6
0
1
2
3
4
5
Unless and Until
The unless and until statements are similar to if and while, except they are executed while their conditionals are false, whereas if and while statements are executed while their conditionals are true.
Note: Unless is a negated form of if, until is really a negated form of while.
Unless
For Example:
1
2
3
4
5
6
i = 20
unless i == 20
puts "i is not 20"
else
puts "i is 20"
end
You can also use unless as a statement modifier:
1
2
age = 0
puts age += 3 unless age > 5
Until
For Example:
1
2
3
4
5
age = 0
until age == 5
puts age
age += 1
end
Output:
1
2
3
4
5
0
1
2
3
4
Use of until with Begin/End, example:
1
2
3
4
5
age = 0
begin
puts age
age += 1
end until age == 5
Like while, you can also use until as a statement modifier:
1
2
age = 0
puts age += 1 until age > 28
The loop
The loop method comes from Kernel. It lets you run a loop continuously.
For Example:
1
2
3
4
5
6
loop do
print "Type something: "
line = gets
break if line = "bye"
puts line
end
The gets method from Kernel retrieves what you type, and it is assigned to a line variable.
However, if line matches “bye” string, you will break out of loop, otherwise, puts prints the contents of line to standard output and the cycle will continue.
The for Loop
1
2
3
for i in 1..5 do
print i, " "
end
1
1 2 3 4 5
Note: Do is not compulsory in the for statement, but for loop on one line, you have to use the do again.
For Example:
1
for i in 1..5 do print i, " " end
1
1 2 3 4 5
For Example:
This below code prints the multiplication table of 2.
1
2
3
for i in 1..10
print "2 x " + i.to_s + " = ", i * 2, "\n"
end
The times Method
It is a integer method.
Comparison between for and times in ruby.
For
1
2
3
for i in 1..10
print i, " "
end
1
1 2 3 4 5 6 7 8 9 10
Times
1
10.times { |i | print i, " " }
1
0 1 2 3 4 5 6 7 8 9
The Upto Method
The Integer,String, and Date classes all have upto methods.
For example, here is a for loop that prints out a list of numbers.
1
2
3
for i in 1..10
print i, " "
end
1
1 2 3 4 5 6 7 8 9 10
For generating the same output with upto method.
1
1.upto(10) { |i| print i, " " }
1
1 2 3 4 5 6 7 8 9 10
Here is another example of upto that prints out a times table for 2.
1
1.upto(10) { |i| print "2 x " + i.to_s + " = ", i * 2, "\n"}
The downto Method
The downto method is similar to upto but counts in the other direction.
Both the Integer and Date classes have downto methods.
For Example:
1
5.downto(1) { |i| print i, " " }
1
5 4 3 2 1
Downto Example with Time Class
1
2
3
4
5
6
7
8
9
def timer( start )
puts "Minutes: " + start.to_s
start_time = Time.now
puts start_time.strftime("Start to_time: %I:%M:%S %p")
start.downto(1) { |i| sleep 30 }
end_time = Time.now
print end_time.strftime("Elapsed time: %I:%M:%S %p")
end
timer 1
Output:
1
2
3
Minutes: 1
Start to_time: 08:57:23 PM
Elapsed time: 08:57:53 PM
The Time class is one of Ruby’s built-in classes. Time’s now method takes a snapshot of the current time, and the strf time method returns a formatted string using formatting directives: %I for hour, %M for minutes, and %S for seconds.
The Kernel method sleep halts the execution of a program for some time. sleep 6 will sleep for 6 seconds. For a longer duration, you can also use sleep(6.minutes) or sleep(6.hours).
Strings
You can also use the command line to get information on a method.
For Example, to get information on the String instance method chop,type:
1
ri String#chop [or] ri String.chop
You can use # or . between the class and method names when returning two methods with ri.
Creating Strings
This line creates a new, empty string called title:
1
title = String.new # => ""
You can test a string to see if it is empty with empty?:
1
title.empty? # => true
The new method can take a string argument:
1
title = String.new( "My name is Sheriff" )
Now we can check if the title string is empty or not, and also the length of the String.
1
2
3
title.empty? # => false
title.length # => 18
You can also test it’s length or size:
1
title.length [or] title.size # => 0
Another way to create a string is with Kernel’s String method:
1
2
3
title = String("My name is Sheriff")
puts title # => My name is Sheriff
Final way to create a String would be, using just an assignment operator and a pair of double quotes:
title = “My name is Sheriff”
You can also use single quotes:
title = ‘My name is Sheriff’
The difference between using double quotes versus single quotes is that double quotes interpret escaped characters and single quotes preserve them.
Here’s what you get with double quotes (interprets \n as a newline):
1
2
3
4
title = "My name is \nSheriff"
puts title # => My name is
#Sheriff
With single quotes (preserves \n in context):
1
2
3
title = 'My name is \nSheriff'
puts title # => My name is Sheriff
General Delimited Strings
Another way to create strings is with general delimited strings, which are all preceded by a % and then followed by a matched pair of delimiter characters, such as !, { ,or [ (must be non-alphanumeric).
The string is embedded between the delimiters.
All of the following examples are delimited by different characters (you can even use quote characters):
1
2
3
4
5
comedy = %!This is a String!
history = %[This is also a String]
tragedy = %(Final String)
You can also use
%Q
is the equivalent of a double-quoted string.
%q
is equivalent to a single-quoted string.
%x
for a back-quoted string (`) for command output.
Concatenating Strings
Adjacent strings can be concatenated simply because that they are next to each other:
1
"Hello," " " "Sheriff" "!" # => "Hello, Sheriff!"
You can also use the +
method:
1
"Hello," + " " + "Sheriff"+ "!" # => "Hello, Sheriff!"
NOTE: You can even mix double and single quotes, as long as they are properly paired.
Another way to do this is with the <<
method. You can add a single string:
1
"Hello, " << "Sheriff!" # => Hello, Sheriff!
Or you can chain them together with multiple calls to<<:
1
"Hello," << " " << "Sheriff" << "!" # => Hello, Sheriff!
An alternative to << is the concat
method:
Note: Concat does not allow chaining.
1
2
3
greeting = "Hello, "
name = "Sheriff!"
greeting.concat(name)
Freeze Method
You can make a string immutable with Object’s freeze
method:
1
2
3
greet = "Hello, Sheriff!"
greet.freeze
After freezing a String, you cannot append to the string, or makes changes to them.
1
greet.concat("!") # => TypeError: can't modify frozen string
You can then ask a object if it is frozen.
For Example:
1
greet.frozen? # => true
Accessing Strings
You can extract and manipulate segments of a string using the String method []
.
It’s an alias of the slice method.
1
line = "Ruby is a programming language!"
If you enter a string as the argument to []
, it will return that string, if found:
1
line['programming'] # => "programming"
Otherwise, it will return nil.
You can use an offset and length (two Fixnum Integers) to tell []
the index location where you want to
start, and then how many characters you want to retrieve:
1
line[5, 2] # => "is"
You can also use range to grab a range of characters. Two dots(..) means inclusion of last characters.
1
line[0..6] # => "Ruby is"
Three dots (…) means exclude the last value.
1
line[0...6] # => "Ruby i"
Using Regular Expression:
1
line[/language!$/] # => "language!"
The regular expression /language!$/ asks, “Does the word language, followed by! come at the end of the line ($)?”.
If this is true, this call returns horse!; nil
if not.
The index method returns the index location of a matching substring.
So if you use index like this:
1
line.index('i') # => 5
Also, you can display the character itself using.
1
line[line.index('i')] # =>"i"
Capitalize
1
2
line = "ruby is a programming language!"
line.capitalize # => "Ruby is a programming language!"
Comparing Strings
If you need to test two strings to see if they are the same or not. You can do that with the ==
method.
1
2
3
"Sheriff" == "Sheriff" # => true
"Sheriff1" == "Sheriff" #=> false
Note: You could also apply the eql? method and get the same results,
though eql?
and ==
are slightly different.
[Reference: https://batsov.com/articles/2011/11/28/ruby-tip-number-1-demystifying-the-difference-between-equals-equals- and-eql/]
Both == and eql? implement value equality checks - they are not interested in whether two variables point to the same object in memory, but whether two objects are equal in terms of their values. For instance “cat” and “cat” might very well be two completely different String objects, but they are quite obviously the same as far as their value is concerned.
In the Object class eql? is synonym with ==. Most subclasses continue this tradition, but there are a few classes that provide a different implementation for eql?. Numeric types, for example, perform type conversion across ==, but not across eql?.
1
2
3
4
5
1 == 1 # true
1.eql? 1 # true
1 == 1.0 # true
1.eql? 1.0 # false
1.0.eql? 1.0 # true
Another way to compare strings is with the <=> method, commonly called the spaceship operator.
It compares the character code values of the strings, returning -1 (less than), 0(equals), or 1(greater than), depending on the comparison, which is case-sensitive:
1
2
3
4
5
6
7
"a" <=> "a" # => 0
"a" <=> 97.chr # => 0
"a" <=> "b" # => -1
"a" <=> "`" # => 1
A case-insensitive comparison is possible with casecmp
, which has the same possible results as <=> (-1,0,1) but
does not care about case:
1
2
3
4
5
6
7
"a" <=> "A" # => 1
"a".casecmp "A" # => 0
"sheriff hussain".casecmp "Sheriff Hussain" # => 0
"Sheriff Hussain".casecmp "Roman Prasad" # => 1
Manipulating Strings
Here’s a fun one to get started with. The *
method repeats a string by an integer factor:
1
"Sheriff! " * 2 # => "Sheriff! Sheriff! "
1
2
taf = "That's ".downcase * 3 + "all folks!" # => "that's that's that's all folks!"
taf.capitalize # => "That's that's that's all folks!"
Inserting a String in a String
The insert method lets you insert another string at a given index in a string.
For Example:
1
2
3
"Learn Rub".insert 9, "y" # => "Learn Ruby"
"Learn Rub".insert 9, "y easily" # => "Learn Ruby easily"
"Learn ".insert 5, "Ruby " * 5 # => "LearnRuby Ruby Ruby Ruby Ruby "
Changing All or Part of a String
With the []=
method you can alter a part or the whole string.
1
2
3
string = "Learn Ruby!"
string["Ruby"]= "Java"
puts string #=> "Learn Java!"
Manipulating Strings
If you specify a Fixnum(integer) as an index, it the corrected string you place at the index location.
1
string[6]= "J" # =>"J"
You can also give two Fixnum(integer) as index to the []
method.
The index of the substring where you want to start, and then how many characters you want to retrieve.
1
2
string = "Learn Ruby!"
string[6,5] # => "Ruby!"
You can also enter a range to retrieve or change range of characters.
1
2
3
string = "Learn Ruby!"
string[6..11]= "Java"
puts string # => "Learn Java"
The delete Method
With delete
or delete!
, you can delete characters from a string:
1
"That's call folks!".delete "c" # => "That's all folks"
Let’s say you want to get rid of that extral inalll:
1
"That's alll folks".delete "l" # => "That's a foks"
Substitute the Substring
Using gsub(or gsub!) replaces a substring (first argument) with a replacement string (second argument):
1
2
"That's alll folks".gsub "alll", "all" # => "That's all folks"
"That's alll folks".gsub "lll", "ll" # => "That's all folks"
Replace method
The replace
method replaces the whole string and not just a substring.
1
2
learning = "Learn Ruby!"
learning.replace = "Learn Java!!!"
When you use replace
, learning remains the same object, with the same object ID, but when you assign the string
to learning twice, the object and its ID will change.
So, to demonstrate
1
2
3
4
5
6
7
8
9
learning = "Learn Ruby!"
learning.object_id # => 47411504419700
learning.replace "Learn Java!!!"
learning.object_id # => 47411504419700
learning = "Learn Ruby!"
learning.object_id # => 47411505386440
learning = "Learn Java!"
learning.object_id # => 47411505412120
Reverse Method
With the reverser method you can reverse the string.(or reverse!
for permanent change).
For Example:
1
"abcdefghijklmnopqrstuvwxyz".reverse # => "zyxwvutsrqponmlkjihgfedcba"
From a String to an Array
split
method converts a string to an array.
1
"0123456789".split # => ["0123456789"]
Using Regular expressions,
A regular expression (//) cuts up the original string at the junction of characters.
1
"0123456789".split( // ) # => ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
In the next example, the regular expression matches a comma and a space (/, /):
1
2
3
names = "Sheriff, Sumin, Suman, Rojan"
names.split(/, /) #=> ["Sheriff", "Sumin", "Suman", "Rojan"]
Case Conversion
1
"learn ruby. ruby is an easy language".capitalize #=> "Learn ruby. ruby is an easy language"
The capitalize
only capitalizes the first letter of the string, not the beginning of succeeding sentences.
Iterating Over a String
each_byte
method takes a string apart byte by byte, returning the decimal value for the character at each index
location.
For Example:
1
2
3
4
5
6
7
8
"Sheriff".each_byte {|byte| puts byte}
# => 83
# 104
# 101
# 114
# 105
# 102
# 102
NOTE: Note: This example assumes that a character is represented by a single byte, which is not
always the case. The default character set for Ruby is ASCII, whose characters may be represented by bytes.
However, if you use UTF-8, characters may be represented in one to four bytes. You can change your character set from
ASCII to UTF-8 by specifying $KCODE = 'u'
at the beginning of your program.
Convert each decimal to its character equivalent with Integer’s chr method
1
2
3
4
5
6
7
8
"Sheriff".each_byte {|byte| puts byte.chr}
# =>S
# h
# e
# r
# i
# f
# f
Or append the output to an array—out:
1
2
3
4
5
6
7
8
9
10
11
out = [] # create an empty array
"Sheriff".each_byte { |b| p out << b}
# => [83]
#[83, 104]
#[83, 104, 101]
#[83, 104, 101, 114]
#[83, 104, 101, 114, 105]
#[83, 104, 101, 114, 105, 102]
#[83, 104, 101, 114, 105, 102, 102]
Incrementing Strings
1
2
"a".next # => "b"
"a".succ # => "b"
You can increment strings with next
and next!
(or succ
and succ!
).
Next only increments the rightmost character:
1
"aa".next # => "ab"
It adds a character when it reaches a boundary, or adds a digit or decimal place when appropriate.
For Example:
1
2
3
4
5
6
7
"z".next # => "aa" # two a's after one z
"zzzz".next # => "aaaaa" # five a's after four z's"
99.0".next # => "99.1" # increment by .1
"99".next # => "100" # increment from 999 to 1000
Also based on the character set in use (ASCII in these examples):
1
" ".next # => "!"
Next also supports chaining.
For Example:
1
"0".next.next.next # => "3"
NOTE: The Date,Generator,Integer, and String classes all have next methods.
Upto Method
For Example:
1
2
"a".upto("z") { |i| print i }
# => abcdefghijklmnopqrstuvwxyz
Using a for
loop and an inclusive range, would give the same result.
1
2
3
4
for i in "a".."z"
print i
end
# => abcdefghijklmnopqrstuvwxyz
Converting Strings
You can convert a string into a float ( Float ) or integer ( Fixnum ) using to_f
and to_i
methods
respectively.
For Example:
1
2
3
4
5
6
7
8
9
# String to Float
"200".class # => String
"200".to_f # => 200.0
"200".to_f.class # => Float
# String to Integer
"100".class # => String
"100".to_i # => 100
"100".to_i.class # => Fixnum
To convert String into Symbol we use to_sym
or intern
methods.
1
2
"name".intern # => :name
"name".to_sym # => :name
Note: The value of the string, not its name, becomes the symbol.
For Example:
1
2
name = "Sheriff"
name.intern #=> :Sheriff
We can also convert an object to a string with to_s
method.
Ruby calls the to_s method from the class of the object, not the String class.
1
2
(256.0).class # => Float
(256.0).to_s # => "256.0"
Regular Expressions:
A regular expression is a special sequence of characters that helps you match or find other strings or sets of strings, using a specialized syntax held in a pattern.
1
sentence = "My name is Sheriff \n I like learning Ruby\n"
Note, that this string contains two lines, set off by the newline character \n. You can match the first line just by using a word in the pattern:
1
sentence.lines.grep(/sheriff/) # => ["My name is Sheriff\n"]
NOTE: grep
is not a String method, it comes from the Enumerable module, which the String class includes.
grep takes a pattern as an argument, and can also take a block
NOTE: Since ruby moved grep from string method to enumerable, we use the lines
method that returns an array of lines
in string.
When you use a pair of square brackets ( [] ), you can match any character in the brackets.
For Example:
1
sentence.lines.grep(/i[sn]/) #=> ["Learning Ruby is quite easy"]
The /i[sn]/
matches for both “in” and “is” strings.
Alternation lets you match alternate forms of a pattern using the pipe character ( | )
:
1
2
3
sentence = "Learning Ruby is quite easy in laptop"
sentence.lines.grep(/is | in/) # => ["Learning Ruby is quite easy in laptop"]
sentence.lines.grep(/ig | in/) #=> ["Learning Ruby is quite easy in laptop"]
Anchors anchor a pattern to the beginning ( ^ ) or end ( $ ) of a line:
1
2
3
sentence = "Learning Ruby is quite easy in laptop"
sentence.lines.grep(/^Learning/) # => ["Learning Ruby is quite easy in laptop"]
sentence.lines.grep(/laptop$/) #=> ["Learning Ruby is quite easy in laptop"]
The ^ means that a match is found when the text “Learning” in is at the beginning of a line, and $ will only match “laptop” if it is found at the end of a line.
Shortcut syntax
Shortcut syntax is a single character preceded by a backslash. For example, the \d shortcut represents a digit which is the same as using [0-9]. Similarly to ^ , the shortcut \A matches the beginning of a string, not a line.
For Example:
1
sentence.lines.grep(/\ALearning/) #=> ["Learning Ruby is quite easy in laptop"]
Similar to $, the shortcut \Z matches the end of a string.
For Example:
1
sentence.lines.grep(/laptop\Z/) #=> ["Learning Ruby is quite easy in laptop"] #=> ["Learning Ruby is quite easy in laptop"]
Math
In most of the programming languages, numbers are primitives, or basic building blocks, that are used by other objects to create logic. In Ruby even numbers are objects.
For Example:
1
2
3
2.class # => Fixnum
2.0.class # => Float
2_000_000_000.class # => Bignum
Numeric
The base class for numbers.
Integer
The basic integer class, and the basis for the Fixnum class.
Float
The class for real or floating-point numbers, based on the computer’s native capacity to represent double-precision.
Fixnum
The main integer class, based on what the computer can hold in a native machine word, such as 32 bits or 64 bits, minus 1.
Bignum
The class of integers outside the range of the basic, native machine word.
Math
A module that holds math functions (as methods).
Precision
A module for approximating the precision of real numbers.
Rational
A class that represents fractional numbers.
Complex
A class that represents complex numbers, which extend real numbers with imaginary numbers (x + iy)
Matrix
A class for creating mathematical matrixes.
Ancestor method
Call ancestors on a class name to see its inheritance hierarchy, like this:
1
Fixnum.ancestors # => [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
We can also use the included_modules
method to discover what
modules a class uses:
1
2
3
4
Object.included_modules # => [Kernel]
Numeric.included_modules # => [Comparable, Kernel]
Integer.included_modules # => [Precision, Comparable, Kernel]
Fixnum.included_modules # => [Precision, Comparable, Kernel]
Converting Numbers
Using Integer
method in the Kernel we can convert a number from another form into an integer.
For Example:
1
2
3
4
5
6
7
8
9
10
Integer(2.4) # => 2 convert a floating-point number
Integer("100") # => 100 convert a string
Integer("0b111") # => 7 convert a binary number from a string
Integer(0177) # => 127 convert an octal number
Integer(0x20) # => 32 convert a hexadecimal number
Floating-point numbers are rounded down.
Integer honors the 0 (octal), 0b (binary), and 0x (hexadecimal) prefixes, whether they’re in strings or not.
You can also create or convert floating-point numbers with Kernel ’s Float method.
1
2
3
Float(100) # => 100.0 convert an integer
Float("100") # => 100.0 convert a string
Division and Truncation
When you do integer division, any fractional part in the result will be truncated.
1
2
3
4
5
6
7
24 / 2 # no problem => 12
25 / 2 # truncation => 12
25.0 / 2 # using a float as at least one operand solves it => 12.5
25.0 / 2.0 # same when both operands are floats => 12.5
Assignment Operator
NOTE: Ruby does not have the increment ( ++ ) or decrement ( – ) operators that C and other languages have.
1
2
3
4
5
6
7
x = 12 # regular assignment
x += 6 # addition
x -= 12 # subtraction
x *= 4 # multiplication
x /= 8 # division
x **= 2 # power (exponentiation)
x %= 3 # modulo
Ranges
Ranges are intervals with a start value and an end value, separated by a range operator.
There are two range operators, .. (two dots) and … (three dots).
The range operator .. means an inclusive range of numbers.
For example, 1..10 means a range of numbers from 1 to 10, including 10 ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 9 , 10 ). The range operator … means an
The exclusive range of numbers are the ones that exclude the last in the series, in other words, 1…10 means a range of numbers from 1 to 9 , as the 10 at the end of the range is excluded ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 9 ).
The === method determines if a value is a member of, or included in, a range, as you can see in these lines of code:
1
2
3
(1..10) === 4 # => true
(1..10) === 16 # => false
(1...10) === 10 # => false, out of range if ... used
When a range is used as an iterator, each value in the sequence is returned. So you can use a range to do things like create an array of digits:
1
(1..9).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
With the Range class, you can also create a range like this:
1
2
digits = Range.new(1, 9)
digits.to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
Inquiring about numbers
1
2
3
op = 0
op.zero? # => true
1.nonzero? # => 1
The integer?
method comes from the Numeric class.
1
2
3
4
12.integer? # => true
12.0.integer? # => false, as it is a float
-1.integer? # => true
-12.integer? # => true
Check whether a number is finite or infinite with the finite?
and infinite?
float
methods.
NOTE: These methods only work for floats.
1
2
3
4
5
6
0.0.finite? # => true
(-1.0/0.0).finite? # => false
(+1.0/0.0).finite? # => false
0.0.infinite? # => nil
(-1.0/0.0).infinite? # => -1
(+1.0/0.0).infinite? # => 1
Nan method
Check whether a floating-point value is a number at all with Float ’s nan?
.
1
2
3
4
5
val = 1.0
val.nan? # => false
val = 0.0/0.0
val.inspect # => "NaN"
val.nan? # => true
Math methods
For getting absolute values of a number( Bignum , Complex , Fixnum , Float , Numeric , Rational ), use the abs
method.
For Example:
1
2
-20.abs # => 40
20.abs # => 40
Get the ceiling or floor of a number (from Float , Integer , or Numeric ).
1
2
5.8.ceil # => 6
5.8.floor # => 5
Rounding a number with the round
method.
1
2
3
4
100.45.round # => 100
100.49.round # => 100
100.5.round # => 101
100.6.round # => 101
Get the next integer with next
method (or its alias succ
):
1
2
3
1.next # => 2
-2.next # => -1
999.next # => 1000
To get character out of a number use the chr
method.
1
2
3
4
5
97.chr # => "a"
98.chr # => "b"
125.chr # => "}"
126.chr # => "~"
127.chr # => "\177"
NOTE: For a nonprinting character, chr
outputs an octal representation of that character (for
example, \177 is the octal representation of DEL ).
Math functions
The Math module provides a number of math functions (via class methods). I’ll show you how to use a few of them, so you can get started. Math also has two constants, along with its methods.
To find out what constants Math (or any other module or class) has defined, use the constants
method:
1
2
3
Math.constants # => ["E", "PI"] Euler and π
print Math::E # => 2.71828182845905
print Math::PI # => 3.14159265358979
The Math.exp function returns Euler to the power of x.
1
2
Math.exp(1) # => 2.71828182845905
Math.exp(11) # => 59874.1417151978
The Math.sqrt method returns the square root of x.
1
2
3
Math.sqrt(4) # => 2.0
Math.sqrt(16) # => 4.0
Math.sqrt(144) # => 12.0
You can do natural logarithms (base E or Euler) and base-10 logarithms.
1
2
3
4
Math.log(Math::E) # => 1.0
Math.log(1) # => 0.0
Math.log(0) # => -Infinity
Math.log10(100.0) # => 2.0
NOTE: By convention, remember that Ruby methods ending in ! mean that the method makes in-place, or destructive, changes to an object, not to a copy of it.
Arrays
Introduction
Arrays are ordered collections of objects.
Ruby arrays can hold objects such as String , Integer , Fixnum , Hash , Symbol , even other Array object. Any object that Ruby can create, it can hold in an array.
Each element in an array is associated with and referred to by an index. You can refer to the last element of an array with –1, the second to last with –2, and so forth.
Difference in Ruby’s Array and Static programming language’s array
In static, compiled programming languages, you have to guess the size of the array at the time it is created. If an array grows beyond that size, you must copy the array into a temporary one and then create a new, larger array, copying the temporary array into it. Ruby is a dynamic language—as are Perl, Python, and PHP, among others—and therefore lets you grow an array at will, adding elements while it automatically increases the size.
Another interesting distinction is that Ruby can hold arrays with objects of all different types, not just one type, as is common in static languages.
Creating Arrays
One way to create an Array is with the new class method.
1
months = Array.new
You can also test whether an array is empty or not with the empty?
method. In this case:
1
months.empty? # => true
If you want you can set the size of an array like this.
1
2
3
4
5
months = Array.new(12)
#OR
months = Array.new 12
You can return the size of an array with either the size or length method:
1
2
3
months.size # => 12
#OR
months.length # => 12
If you see the elements of the months array they are all nil.
1
months # => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
Also, you can use the inspect
method.
1
puts months.inspect #=> "[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]"
Another form of new lets you assign an object (such as a string) to each element in the array:
1
2
month = Array.new(12, "month") # =>["month", "month", "month", "month", "month", "month", "month", "month", "month",
"month", "month", "month"]
Clear the Array
You can clear out an array with clear
method.
1
2
month.clear # => []
month.empty? # => true
Creating an Array with a Block
You can also use a block with new, populating each element with what the block evaluates to:
1
num = Array.new(10) { |e| e = e * 2 } # => [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Simple way to create an array is:
1
2
months = Array[ "jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec" ]
The Kernel module, included in Object , has an Array
method, which only accepts a single argument. Here, the method takes a
range as an argument to create an array of digits.
1
digits = Array(0..9) # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
But if you submit a set of strings, Array accepts them as a single, concatenated element.
1
names = Array( "Sheriff" "Sumin" "Suman ) # => ["SheriffSuminSuman"]
Array filled with numbers using %w.
1
year = %w[ 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 ] #=>["2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009"]
It treats those numbers as strings.
You can even have an array that contains objects from different classes, not all just one type.
For example:
1
2
mixed_array = ["January", 1, :year, [2006,01,01]]
mixed_array.each {|e| print e.class, " " } # => String Fixnum Symbol Array
You just saw that you can access elements with the []
or at
method.
1
2
3
4
5
months = %w[ January February March ]
months[0] # => "January"
months[2] # => "March"
# You can also use the at method like
months.at(0) # => "January"
NOTE: The at method is supposed to be slightly faster than [].
You can access the last element in the array with -1.
1
2
months[-1] # => "March"
months[-2] # => "Feburary"
Another way to get the first and last elements of an array is with the first and last methods.
1
2
months.first # => January
months.last # => March
Both first and last take integer arguments, indicating the number of elements to return.
1
2
months.first 2 # => ["January", "February"]
months.last 0 # => []
index method
index
method returns the index of the first element that matches the object passed in the argument.
1
2
months.index "February" # => 1
Similarly, rindex
matches the last element that matches the object.
You can sepcify in an array from where to start and the number of elements that you want to retrieve.
1
2
year = [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]
year[0, 4] # => [2000, 2001, 2002, 2003]
The 0 is the start parameter. It says to start at 0 and the second is the length parameter, which tells how many elements you want.
NOTE: You can’t do this with the at method.
You can also use a range:
1
year[0..3] #=> [2000, 2001, 2002, 2003]
NOTE: You can’t use ranges with the at method.
You can also used the slice
method to retrieve elements from the array.
Similar yo []
method, the first argument in slice is the begining element to retrieve, and the second argument is the
length of the element that we want to retrieve.
1
2
3
4
5
year.slice(1) # => 2001
year.slice(0,4) # => [2000, 2001, 2002, 2003]
year.slice(4,5) #=> [2004, 2005, 2006, 2007, 2008]
year.slice(0..2) # => [2000, 2001, 2002]
year.slice(0...2) # => [2000, 2001]
The include method
The include
method is used to test to see if an array includes an element with a given value, returning true or false.
1
2
year.include? 2004 # => true
year.include?( 2010 ) # => false
With the %w
notation. It assumes that all elements are strings (even nil).
For Example:
1
2
months = %w[ nil January February March April May June July August September October
November December ] # => ["nil", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
Concatenation of array
1
2
3
4
q1 = %w[January February March ]
q2 = %w[April May June ]
q3 = %w[July August September ]
q4 = %w[October November December ]
You can concatenate these arrays in several ways. One way is with the +
operator or
method.
1
2
3
half = q1 + q2 # => ["January", "February", "March", "April", "May", "June"]
half2 = q3 + q4 # => ["July", "August", "September", "October", "November", "December"]
year = half + half2 # => ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
Another way to concatenate is with the <<
method.
For Example:
1
2
3
4
5
6
7
8
years = [2000]
years << 2001 # => [2000,2001]
# You can chain these, too:
years << 2003 << 2004 << 2005 # => [2000, 2001, 2003, 2004, 2005]
Finally,
As with +
, you can concatenate one array onto another with concat
.
1
2
3
year = [2001]
year_2 = [2002]
years = year.concat(year_2) # => [2001, 2002]
Note: This concatenated year and year_2 , making a new array, years. Concat always returns a new array, it does not add elements to an existing array the way << does.
Set Operations in Array
Ruby can do several set operations on arrays, such as:
• Intersection with &
• Difference with -
• Union with |
Intersection (&) creates a new array, merging the common elements of two arrays but removing uncommon elements and duplicates.
1
2
3
names = ["Sheriff","Sumin","Suman"]
names_two = ["Sumin","Rojan","Roman"]
names&names_two # => ["Sumin"]
Difference (-) creates a new array, removing elements that appear in both arrays:
1
2
names-names_two #=> ["Sheriff", "Suman"]
names_two-names #=> ["Rojan", "Roman"]
Union (|) joins two arrays together, removing duplicates:
1
names|names_two #=> ["Sheriff", "Sumin", "Suman", "Rojan", "Roman"]
Uniq method
The uniq
method also removes duplicates from a single array, creating a new array.
It’s next-door neighbor uniq!
that changes the array itself, in place.
For Example:
1
2
3
4
5
shopping_list = %w[ cheese bread crackers potatoes carrots cheese ] #=> ["cheese", "bread", "crackers", "potatoes", "carrots", "cheese"]
shopping_list.uniq #=> ["cheese", "bread", "crackers", "potatoes", "carrots"]
shopping_list #=> ["cheese", "bread", "crackers", "potatoes", "carrots", "cheese"]
#No changes to the object
NOTE: The above code does not make changes to the shopping_list array itself, and the results must be assigned
to some other array, for the result to persist. On the other hand is uniq!
is used, changes are made itself to the
current object, i.e. shopping_list.
For Example:
1
2
3
4
5
shopping_list = %w[ cheese bread crackers potatoes carrots cheese ] #=> ["cheese", "bread", "crackers", "potatoes", "carrots", "cheese"]
shopping_list.uniq! #=> ["cheese", "bread", "crackers", "potatoes", "carrots"]
shopping_list #=> => ["cheese", "bread", "crackers", "potatoes", "carrots"]
# Changes are made iteself to the object
Using Arrays as Stack
A stack is a LIFO (last in, first out) structure.
You can use an array like a stack by using the push
and pop
methods from the Array class.
For Example:
1
2
3
4
5
words = %w[hi hello bye] #=> ["hi", "hello", "bye"]
words.push "welcome" #=> ["hi", "hello", "bye", "welcome"]
p words #=> ["hi", "hello", "bye", "welcome"]
words.pop #=> "welcome"
p words #=> ["hi", "hello", "bye"]
Comparing Arrays
Three methods allow you to compare arrays to see if they are equal. Those methods
are ==
, <=>
, and eql?
.
The ==
method compares two arrays to test if they are equal. Two arrays are consid-
ered equal if:
they contain the same number of elements
each element is equal to the corresponding element in the other array (compare with Object’s
==
).
For Example:
1
2
3
4
5
6
7
ram = [ "Budhanilkhanta", 23, true ]
shyam = ["Lalitpur", 23, false]
hari = [ "Budhanilkhanta", 23, true ]
ram == hari #=> true
ram == shyam #=> false
shyam == hari #=> false
Closely related is eql?
. This method will also return true if the objects are the same or if their content is the same.
NOTE: The difference between == and eql? is that eql? checks to see if the values are equal (as in == ), but also checks if the values are of the same type.
For Example:
1
2
3
4
ram = [ "Budhanilkhanta", 23, true ]
hari = [ "Budhanilkhanta", 23.0, true ]
ram == hari #=> true
ram.eql?hari #=> false
Another way to compare arrays is with <=>
(spaceship operator). When a comparison is made, it
determines whether the values of the compared elements are greater than, lesser
than, or equal to each other. Rather than true or false , the comparison returns an
integer: -1 for less than, 0 for equal, and 1 for greater than.
For Example:
1
2
3
ram<=>hari #=> 0
ram<=>shyam #=> -1
shyam<=>hari #=> 1
Changing Elements in an Array
You can use the insert
method to insert elements in an array.
insert, inserts and element without replacing the current element, and increases the size of the array accordinlgy.
1
2
3
years = %w[january feburary march april may june july august] #=> ["january", "feburary", "march", "april", "may", "june", "july", "august"]
years.insert(0,nil) #=> [nil, "january", "feburary", "march", "april", "may", "june", "july", "august"]
years.insert(3,"asd") #=> [nil, "jan", "feb", "asd", "mar", "april", "may", "june", "july", "august"]
You can also use a range to change elements in the array.
For Example:
1
2
years[1..3] = "January", "March", "Feburary" #=> ["January", "March", "Feburary"]
p years #=> [nil, "January", "March", "Feburary", "mar", "april", "may", "june", "july", "august"]
You can also do this with start and length parameters.
1
2
3
years = %w[january feburary march april may june july august]
years[0,3] = "Jan", "Mar", "Feb" #=> ["Jan", "Mar", "Feb"]
p years #=> ["Jan", "Mar", "Feb", "april", "may", "june", "july", "august"]
Join Array
You can extract the elements of an array as a single string using to_s
. to_s
is common to many classes.
1
2
3
4
5
6
names #=> ["Sheriff", "Suman", "Sumin"]
names.join #=> "SheriffSumanSumin"
#Join with space and comma
names.join(",") #=> "Sheriff,Suman,Sumin"
The compact
method removes nil elements from the array.
1
2
names = [nil,"Sheriff","Suman","Sumin"]
names.compact #=> ["Sheriff", "Suman", "Sumin"]
Using shift and unshift
Another way to remove an element from an array is with the shift
method. shift returns the first element of an array
or nil if the array is empty, and then removes the element, shifting all other elements down by one.
It removes the first element in the array rather than the last. (FIFO—first in, first out).
For Example:
1
2
3
dates = [ 4, 5, 6, 7 ]
dates.shift # => 4
p dates # => [5, 6, 7]
Similarly, unshift
is another array method, that pushes element into and array from the front rather than the back.
For Example:
1
2
dates.unshift 4 # => [4, 5, 6, 7]
dates.unshift(2,3) # => [2, 3, 4, 5, 6, 7]
Deleting Elements
The delete
method removes a matching object from an array, returning the deleted
object if found.
For Example:
1
2
names = ["Sheriff","Sumin","Suman"]
names.delete "Sheriff" #=> "Sheriff"
The delete
method also takes block. The result of the block is returned if the object is not found.
1
2
names = ["Sheriff","Sumin","Suman"]
names.delete("cat") {|deletedWord| "#{deletedWord} cannot be found"} #=> "cat cannot be found"
Arrays and Blocks
1
2
3
4
names.each { |e| print e.capitalize + " " }
# Returns the original array
names.each {|name| name.upcase} #=> ["Sheriff", "Sumin", "Suman"]
The above code in line #1, prints each name as a string as follows:
1
SHERIFF SUMIN SUMAN
each
method returns the array itself.
On the other hand, the map
method (and its synonym collect
) is similar to each, but it returns a new
array instead of a string.
1
names.map {|name| name.upcase} #=> ["SHERIFF", "SUMIN", "SUMAN"]
Sorting Things and About Face
1
x = [ 2, 5, 1, 7, 23, 99, 14, 27 ]
Apply the sort
(or sort!
, for in-place changes), and your array will line up it’s elements in numeric order.
1
x.sort! # => [1, 2, 5, 7, 14, 23, 27, 99]
NOTE: In order for an array to be sorted, its elements must be comparable.
It is possible with strings and numbers for comparison. But because Ruby arrays can hold objects of any type, it is possible that the
elements won’t be comparable, and in that case, you won’t be able to sort the elements with sort
or sort!
.
The reverse
method reverses the order of the elements in an array, returning a new array of elements, reversed.
You can also use reverse!
for in-place changes.
1
2
arr = ["one","two","three"]
arr.reverse #=> ["three", "two", "one"]
Multidimensional Arrays
A multidimensional array is an array of arrays. You create such an array by giving array elements that are themselves arrays.
For Example a two-dimensional array looks like this.
1
2
3
d2 = [ ["January", 2007],
["February", 2007],
["March", 2007] ] #=> [["January", 2007], ["February", 2007], ["March", 2007]]
Other Array Methods
To get a list of all the Array methods, type:
1
ri Array
For more information on any method via ri
, type something like this at a command
line:
1
ri Array#map [or] ri Array.map [or] ri "Array.&"
Hashes
A hash is an unordered collection of key-value pairs. A hash is similar to an Array, but instead of a default integer index starting at zero, the indexing is done with keys that can be made up from any Ruby object. The keys in a Hash can even be an Array.
Hashes can be accessed by keys or by values, but usually by keys, which must be unique. Attempting to access a hash with a key that does not exist, the method will return nil, unless the hash has a default value.
Since, the values stored in hashes are unordered, the key-value pairs in a hash are not stored in the same order that they are inserted. The contents of a hash look different from what you put in the contents are not ordered the same way as in an array.
Creating Hashes
There are a variety of ways to create hashes.
- hash with the new class method.
1
months = Hash.new
You can test to see if a hash is empty with empty?
and if it is not, the size or length of the hash.
1
2
3
months.empty? # => true
months.length # => 0
months.size # => 0
NOTE: You can also use new to create a hash with a default value. After you set a default value to a hash, and if you try to access the hash with an undefined key within the hash, the default value that is set is returned.
For Example:
1
2
3
4
months = Hash.new( "hello" )
#OR
months = Hash.new "hello"
months["hi"] #=> "hello"
Since, there is not key that corresponds to the string “hi”, the default value “hello” is returned.
Hash also has a class method []
which can be used to create a hash and can be called in either one of two ways: with a
comma separating the pairs, like this:
1
names = Hash["name","Sheriff","age",22,"sex","male"] #=> {"name"=>"Sheriff", "age"=>22, "sex"=>"male"}
Or with =>
1
names = Hash["name"=>"Sheriff","age"=>22,"sex"=>"male"] #=> {"name"=>"Sheriff", "age"=>22, "sex"=>"male"}
Finally another way to create a hash, is with curly braces, like this:
1
names = {"name"=>"Sheriff","age"=>22,"sex"=>"male"} #=> {"name"=>"Sheriff", "age"=>22, "sex"=>"male"}
Instead of strings, you could also used integers.
For Example:
1
names = {0=>"Sheriff",1=>"Sumin",2=>"Suman"} #=> {0=>"Sheriff", 1=>"Sumin", 2=>"Suman"}
Or Symbols.
For Example:
1
names = {:name=>"Sheriff",:age=>22,:sex=>"male"} #=> {:name=>"Sheriff", :age=>22, :sex=>"male"}
You can use any Ruby object as a key or value, even an array.
For Example:
1
2
names = {["Sheriff",true]=>"male"} #=> {["Sheriff", true]=>"male"}
names[["Sheriff",true]] #=> "male"
Accessing hash value
A simple way of grabbing a value is the []
method. It retrieves a single hash value based on a key.
1
2
names = {0=>"Sheriff",1=>"Sumin",2=>"Suman"}
names[0] #=> "Sheriff"
You can test to see if the hash names has a given key with any of the following methods, which are all synonyms of
each other: key?
, has_key?
, member?
, or include?
.
1
2
names.key? 3 # => false
names.has_key? 3 # => false
You can also see if it has a given value with value?
or has_value?
.
1
2
names.has_value? "Roman" # => false
names.has_value? "Sheriff" # => true
We also have the methods keys
and values
that returns an array containing all the keys
or values in a hash.
1
2
names.keys #=> [0, 1, 2]
names.values #=> ["Sheriff", "Sumin", "Suman"]
Retrieve the values out of a hash based on one or more keys with values_at
.
1
2
names.values_at 0 # => ["Sheriff"]
names.values_at 0,1 # => ["Sheriff", "Sumin"]
With the index
method. The key of the value is returned from the Hash.
For Example:
1
names.index "Sumin" #=> 1
The select
method uses a block to return a new, multidimensional array of key-value pairs.
1
2
zip = { 82442 => "Ten Sleep", 83025 => "Teton Village", 83127 => "Thayne", 82443 => "Thermopolis", 82084 => "Tie Siding", 82336 => "Tipton", 82240 => "Torrington", 83110 => "Turnerville", 83112 => "Turnerville" }
zip.select { |key,val| key > 83000 } # => [[83110, "Turnerville"], [83127, "Thayne"], [83112, "Turnerville"], [83025, "Teton Village"]]
New Syntax to create Hash
Today, there are two different syntax for defining Hashes.
Up to a certain version of Ruby the syntax that uses hash rockets was the only syntax to create Hashes, and it works the same for all Hashes no matter what kinds of objects you use as keys.
A few years back, a new syntax was introduced.Tt takes a little less space, and it also looks a lot like JSON, which is a data format that is widely used in web applications.
The new Hash syntax looks like this:
1
{ one: "eins", two: "zwei", three: "drei" }
Using this syntax we tell Ruby that we want the keys to be symbols. If you define a Hash using this syntax, then you’ll get a Hash that has Symbols as keys.
Symbols are defined by prepending a word with a colon like :one
.
Simply remember that these two Hashes are exactly the same:
1
2
{ :one => "eins", :two => "zwei", :three => "drei" }
{ one: "eins", two: "zwei", three: "drei" }
Iterating over Hashes
You can iterate over hashes with each , each_key , each_value , or each_
pair. Here are the differences.
The each method calls a block once for each key in a hash.
1
2
3
4
5
6
name = {name: "Sheriff", age: 12, gender:"Male"}
name.each {|k,v| puts "#{k} : #{v}"}
# =>
#name : Sheriff
#age : 12
#gender : Male
each
may take one or two parameters, which are passed to the block as two-element
arrays.
The each_pair
method is similar to each except it must take two parameters
and is somewhat more efficient than each
when using both parameters.
The each_key
method passes only the keys to the block.
1
2
3
4
5
name.each_key {|key| puts key}
# =>
#name
#age
#gender
This is similar to the keys
method, which returns all the keys in an array.
The each_value
method passes all the values to a block.
1
2
3
4
5
name.each_value {|value| puts value}
# =>
#Sheriff
#12
#Male
Changing Hashes
Hash ’s []= method replaces or adds key-value pairs to an existing hash. You can use []= to add a pair to this array.
1
2
3
name #=> {:name=>"Sheriff", :age=>12, :gender=>"Male"}
name[:marks]=500
name #=> {:name=>"Sheriff", :age=>12, :gender=>"Male", :marks=>500}
Here, a new symbol :marks
is inserted in the Hash with the value of 500.
1
2
3
name #=> {:name=>"Sheriff", :age=>12, :gender=>"Male", :marks=>500}
name[:name]="Sumin"
name #=> {:name=>"Sumin", :age=>12, :gender=>"Male", :marks=>500}
Here, an existing value of the key :name is changed into Sumin using the []= operator.
Merging Hashes
The merge
method merges two hashes together, producing a copy of the hashes that removes duplicate keys by overwriting
the key-value pairs from the merged array.
1
2
3
4
name # => {:name=>"Sumin", :age=>12, :gender=>"Male", :marks=>500}
names = {age:22,marks:200} #=>{:age=>22, :marks=>200}
name.merge names #=> {:name=>"Sumin", :age=>22, :gender=>"Male", :marks=>200}
The keys and values from names took over the pairs with the same keys in name hash , making age=22 , and and marks = 200.
You can also cherry-pick your values by using merge with a block.
Sorting a Hash:
When you sort a hash with the sort
method, you get a multidimensional array of
two-element arrays in return.
NOTE: When you create a hash, the key-value pairs are not stored in the order they were added. Ruby orders them however it wants to, most likely because the values can be accessed or retrieved via the keys, not by sequence, as with an array.
1
2
3
4
5
rhode_island = { 1 => "Bristol", 2 => "Kent", 3 => "Newport", 4 => "Providence", 5 =>"Washington" }
p rhode_island # => {5=>"Washington", 1=>"Bristol", 2=>"Kent", 3=>"Newport", 4=>"Providence"}
rhode_island.sort # => [[1, "Bristol"], [2, "Kent"], [3, "Newport"], [4,"Providence"], [5, "Washington"]]
Hash does not have a sort! method, to change the contents of the hash in place.