Title: Ruby
1Ruby Ruby on Rails trainingday one Ruby
- RBC Dexia Investor Services
2Pre-requisites
2
3Pre-requisites
- Youre a developer
- You know what variables, assignation, conditional
- structures and loops are
- Youve been taught what Oriented Objet
Programming is - You know what classes, methods and inheritance
are - At least youve heard about it
- Youre willing to learn something new
- Youre open-minded
4Before we start
4
5Before we start
- Do you have Ruby installed ?
- In an MS-DOS terminal, run ruby v
- It should display the interpreter version
- Do you have irb ?
- In an MS-DOS terminal, run irb
- A prompt should appear
- Do you have SciTE ?
- Click on Start, Programs, Ruby-184-20, then SciTE
- It should launch the SciTE text editor
6Okay, lets move on !
6
7Whats Ruby ?
7
8Whats Ruby ?
- A programming language
- Inspired from Perl, Python, Eiffel, Smalltalk,
LISP Ada - Interpreted
- Fully object-oriented
- Dynamic
- Wished as natural as possible by its creator
9A bit of history
- Created by Yukihiro matz Matsumoto
- First version in 1993
- First public release in 1995
- Today in versions 1.8.6-p287, 1.8.7-p72
1.9.1-preview1
2003 1.8.0
1998 1.2.0
2007 1.8.6
1999 1.4.0
2000 1.6.0
10Which Ruby ?
- Ruby (MRI), written in C
- Ruby 1.9 (YARV), written in C too
- Ruby Enterprise Edition, a modified Ruby 1.8.6
- JRuby, a 1.8.5-compatible interpreter, written
in JAVA - IronRuby, a .NET implementation
- MagLev, written in Smalltalk
- Rubinius, written in Smalltalk too
11Basic syntax
11
12Basic syntax identifiers
local variables are lower-case strings (no
camel case by convention) count result_item
global variables have a leading dollar
sign application_wide_parameter LOAD_PATH
constants starts with an upper-case
char MyPassword RUBY_PLATFORM
13Basic syntax litterals
numbers 42 3.1415 strings 'I () lt3
Ruby' "it's training day\n" "welcome abroad,
name"
14Basic syntax litterals
arrays / lists 1, 2, 3, 4 "Earth",
"Wind", "Fire" hash tables language gt
"Ruby", version gt 1.8 "January" gt 31,
"February" gt 29
15Basic syntax symbols
symbols are suites of characters starting with
a colon key success although anything with a
leading colon can be a symbol, the convention is
to use lower-case ones ResultKey KEY "the key"
16Basic syntax operators
Ruby offers a lot of operators, like these for
example a 5 a 2 a - 1 a 3 a 10 a 2 a
4 a ! 4 a lt 2 a gt 2
17Basic syntax operators
and like these, too 5..45 5...45 not true true
false true and false true false true or
false a 5 a 9 a 10
18Basic syntax operators
In Ruby, and -- dont exist. Use 1 and -
1 and are operators you can (re)define
Ruby wouldnt know what to add for non-integer
values.
Tip
don't write this a b-- but this a 1 b
- 1
19Basic syntax conditional structures
if / then / else statement if answer 42
puts "Yes, this is the answer" else puts "No,
answer is not the answer" end the ternary
operator exists in Ruby too answer 42 ? (puts
"Yes") (puts "No")
20Basic syntax conditional structures
if / then / elsif statement is pretty much the
same if answer 42 puts 'Yes, this is the
answer' elsif (answer 41) or (answer 43)
puts "You're close to the answer !" else puts
"No, answer is not the answer" end you can
write simple conditions on one line if answer
42 then puts "Yes" end
21Basic syntax conditional structures
unless can replace if when necessary unless
answer 42 puts "No" else puts "Yes" end
one line forms can be reversed puts "Yes" if
answer 42 puts "No" unless answer 42
22Basic syntax loop structures
while loop statement i 1 while i lt 10 puts
i i 1 end you can write it on one
line while i lt 10 do puts i i 1 end
23Basic syntax loop structures
while loop statement, with the condition at the
end i 1 begin puts i i 1 end while i lt
10 you can reverse the one line form (puts i
i 1) while i lt 10
24Basic syntax exercise
- Write a Ruby script which will
- Make the user guess a number between 0 and 10
(included) - Congratulates him or her when he or she succeeds
- Counts how many times it took the user to find
the right number - Help
- Use rand(n) to get a random value
- Use gets to catch the user input
- Remember we need an integer
- Use puts(text) to display a text on the terminal
25Basic syntax solution
number rand(10) tries 1 puts "I'm thinking
about a number between 0 and 10, these
included" puts "Guess which one ?" while
(gets.to_i ! number) puts "No, this is not the
right number" tries 1 end tries tries
1 ? "1 try" "tries tries" puts "Wonderful,
you guessed it in only tries !"
26Basic syntax
... tries 1 end tries tries 1 ? "1
try" "tries tries" puts "Wonderful, you
guessed it in only tries !"
- Remember that, in Ruby
- Expressions are evaluated from right to left
- The last value or expression evaluated is always
returned
27Basic syntax exercise
- Improve your Ruby script to
- Tell the user if the number is lower or greater
than his or her input - Help
- No help
28Basic syntax solution
number rand(10) tries 1 puts "Which number
am I thinking about ?" input gets.to_i while
input ! number input gt number ? puts("No, it's
lower !") puts("No, it's greater !") tries
1 input gets.to_i end tries tries 1 ?
"1 try" "tries tries" puts "Wonderful, you
guessed it in only tries !"
29Basic syntax loop structures
input gets.to_i while input ! number input gt
number ? puts("No, it's lower !") puts("No,
it's greater !") tries 1 input
gets.to_i end could have been written while
(input gets.to_i) ! number input gt number ?
puts("No, it's lower !") puts("No, it's greater
!") tries 1 end
30Basic syntax loop structures
until loop statement i 1 until i 10
puts i i 1 end again, you can write it on
one line until i 10 do puts i i 1 end
31Basic syntax loop structures
until loop statement with the condition at the
end i 1 begin puts i i 1 end until i
10 you can reverse the one line form (puts i
i 1) until i 10
32Basic syntax exercise
- Modify your Ruby script to
- Replace the while loop with an until one
- Help
- No help
33Basic syntax solution
number rand(10) tries 1 puts "Which number
am I thinking about ?" input gets.to_i until
input number input gt number ? puts("No, it's
lower !") puts("No, it's greater !") tries
1 input gets.to_i end tries tries 1 ?
"1 try" "tries tries" puts "Wonderful, you
guessed it in only tries !"
34Basic syntax loop structures
You can modify the normal loop flow The break,
next and redo instructions allow you to escape
from a loop, go directly before or after the
condition.
Tip
i 0 while i lt 10 i 1 next if i lt 5
puts i end this prints 5, 6, 7, 8 and 9
i 0 while i lt 10 i 1 break if i 4
puts i end this prints 1, 2 and 3, then stops
i 0 while i lt 10 i 1 redo if
i.modulo(2) ! 0 puts i end this prints the
even number up to 10
35Basic syntax conditional structures
the case/when/else statement case RUBY_VERSION
when '1.8.4' puts "you're using our
version" when /1\.8/ puts "you're using a
stable version" when /1\.9/ puts "aren't
you scared of using that ?" else puts
"it's more than time to upgrade !" end
36Basic syntax conditional structures
case statement with ranges case age when
0..12 puts "you're a child" when 13..19
puts "you're a teen" when 20..99 puts
"don't worry, you're still young !" else end
37Basic syntax exercise
- Modify your Ruby script to
- Replace the if condition with a case / when one
- Remind the user the right range of values if his
or her input is - not correct
- Help
- No help
38Basic syntax solution
number rand(10) tries 1 puts "Which number
am I thinking about ?" while (input gets.to_i)
! number tries 1 puts case input
when 0..(number - 1) "No, it's greater !"
when (number 1)..10 "No, it's lower !"
else "The number is in the 0 - 10 range"
end end puts "Wonderful, you guessed it in only
tries time's' if tries gt 1!"
39Basic syntax exceptions
begin 2 / x rescue puts "something went
wrong" else puts "it went fine" ensure puts
"the calculation has finished" end
40Basic syntax exceptions
begin 2 / x rescue ZeroDivisionError puts
"you can't divide by 0 do you remember your
math lessons ?" rescue TypeError puts "did you
provide a number ?" rescue puts "something went
wrong, but what ?" ensure puts "the calculation
has finished" end
41Basic syntax defining methods
the method name is in downcase def
say_hello_to(name) puts "Hello name
!" end say_hello_to "David gt Hello David
! say_hello_to gt ArgumentError wrong number
of arguments (0 for 1)
- Remember that, in Ruby
- Theres no type verification in method signature
- Mismatches occur at execution time, and lead to
exceptions raised
42Basic syntax defining methods
optional parameter def say_hello_to(name"you")
puts "Hello name !" end say_hello_to
"David gt Hello David ! say_hello_to gt
Hello you ! say_hello_to "David", "Mickael gt
ArgumentError wrong number of arguments (2
for 1)
43Basic syntax defining methods
multiple parameters def say_hello_to(names)
puts "Hello names.join(', ')
!" end say_hello_to "David gt Hello David
! say_hello_to gt Hello ! say_hello_to
"David", "Mickael gt Hello David, Mickael !
44Basic syntax defining methods
multiple parameters def send_invitation(message,
names) puts names.class gt Array
... end
- Remember that, in Ruby
- The splat parameter is always an Array
- It must be the last parameter
45Basic syntax requiring files
- As your code grows, you may want to split it
into - multiple files
- The maintainability of your program benefits
from it - A Ruby script can load or require external
source files
46Basic syntax requiring files
require "ext requires the ext.rb file located
in the LOAD_PATH the extension is optional
the interpreter first look for .rb, then .so
files require returns true the first time it
loads the file, false the others load "ext.rb
loads the ext.rb file, even if it has already
been read the extension is mandatory load
returns true if the load is successful
47Basic syntax exercise
- Write a Ruby script which will
- Require another one
- Make use of the methods located in this second
file - Help
- No help
48Basic syntax solution
file extra_methods.rb def train(name) puts
"name gets a Ruby training" end file
my_script.rb require "extra_methods" train
"Antoine" gt Antoine gets a Ruby
training train "Christelle" gt Christelle
gets a Ruby training
49Basic syntax regular expressions
regular expressions in Ruby "ruby"
/ru/ gt 0 "ruby" /by/ gt 2 "ruby"
/java/ gt nil "ruby on rails"
/ruby\s/ gt 0 "ruby on rails" /\s/
gt 4
50Basic syntax regular expressions
reminders about regular expressions the
beginning of the line the end of the
line . any character \. the dot
character \s a space character \S not a
space character \d a digit \D not a
digit \w an alphanumeric character
51Basic syntax regular expressions
reminders about regular expressions \A the
beginning of a string \z the end of a
string \n a new line \t a tab \1 \2 ...
\9 the n-th group of the expression a-z
anything in the a to z range of
characters aeiouy anything not one of this
character modifier /ruby/i case
insencitive
52Basic syntax regular expressions
quantifiers ruby zero or more y
char ruby one or more y char ruby2
exactly two y chars ruby2,5 between two and
five, both included groups (\d) groups and
captures what matches (?\d) groups without
capturing condition rubyrails rub, then the
y or r char, then ails
53Basic syntax namespace
defines a Greetings namespace module Greetings
GREET_WORDS "Hello", "Hi" def
Greetingswelcome(name) puts "Welcome
name" end end puts GreetingsGREET_WORDS0
gt Hello Greetingswelcome "David gt
Welcome David
54Basic syntax namespace
you can define modules into others module
Greetings module Messages module Basic
def welcome(name) puts "Welcome
name" end end end end GreetingsM
essagesBasicwelcome "David gt Welcome David
55Object-oriented programming
55
56OOP Objet-oriented programming
- In Ruby, (nearly) everything is an object
- Even when, previously, you called puts, you
called a method - When you created methods, they were defined for
Object - You call methods on object as this
ltobjectgt.ltmethodgt - More precisely, in Ruby, you send messages to
objects
57OOP everything is an object
42.class
gt Fixnum 3.1415.class
gt Float "it's training
day".class gt String 1,
2, 3, 4 .class
gt Array language gt "Ruby", version gt 1.8
.class gt Hash key.class
gt Symbol true.class
gt
TrueClass false.class
gt FalseClass nil.class
gt NilClass
58OOP manipulating objects
42.succ gt 43 3.1415.round
gt 3 "it's training day".split
gt "it's", "training", "day" 1, 2, 3, 4
.size gt 4 language gt "Ruby",
version gt 1.8 .keys gt language,
version key.to_s gt
"key" true.send(, true) gt
true false.send(, true) gt
false nil.nil? gt true
59OOP manipulating objects
language gt "Ruby", version gt 1.8 .keys
gt language, version key.to_s gt
"key" true.send(, true) gt
true false.send(, true) gt
false nil.nil? gt true
- Remember that, in Ruby
- Your method name can end with a ? or an !
- By convention
- Methods ending with a ? return true or false
- Methods ending with an ! are destructive they
modify the receiver
60OOP class definition
class Dog class definition def
initialize(name) initialize is the
post-constructor _at_name name initializing
an instance variable end def barks this
is an instance method puts "_at_name barks !
Woof ! Woof !" end end end of class
definition
61OOP instancing a class
medor Dog.new gt ArgumentError wrong number
of arguments (0 for 1) medor Dog.new medor
gt ltDog0x2efa478 _at_name"medor"gt medor.is_a?
Dog gt true medor.barks gt medor
barks ! Woof ! Woof ! milou Dog.new "milou
gt ltDog0x2ef2fe8 _at_name"milou"gt milou.class
gt Dog milou.barks gt milou barks !
Woof ! Woof !
62OOP exercise
- Write a Ruby script which will
- Contain a Dog class
- Instantiate at least twice the Dog class
- Make these dogs make funny things
- Allow them to play together (xxx and yyy play
together) - Help
- Be inventive !
63OOP solution
class Dog ... def name _at_name
returns the name of the dog end def
plays_with(another_dog) takes one argument
puts "_at_name and another_dog.name play
together" end end
64OOP duck-typing
def name _at_name returns the name of the
dog end def plays_with(another_dog) takes
one argument puts "_at_name and
another_dog.name play together" end
- Remember that, in Ruby
- An objects class isnt that important
- What is important is the object behaviours, what
it can do - Which methods it responds to
65OOP specializing an object
def milou.to_the_rescue puts "milou helps
Tintin to get out a dangerous situation" end milo
u.to_the_rescue gt milou helps Tintin to get
out a dangerous situation medor.to_the_rescue
gt NoMethodError undefined method
to_the_rescue' for ltDog0x2efae64
_at_name"medor"gt
66OOP classes
- In Ruby, classes are objects too
- They belong to a class Class
- They have variables
- They have methods
67OOP class variables and methods
class Dog _at__at_count 0 this is a class
variable def Dog.count defines a new class
method _at__at_count end def initialize
_at__at_count 1 class variables are accessible
from the instance too end end
68OOP self context
- In Ruby, self is a reference to the current
object - There is always a current object
- In a method, self is the object
- In a class definition, self is the class
- In a module definition, self is the module
69OOP class variables and methods
class Dog _at__at_count 0 def self.count you
can replace Dog by self _at__at_count as it
refers the class end def initialize
_at__at_count 1 end end
70OOP class variables and methods
class ltlt self is the geeky way of adding
methods to a class. The eigenclass of an object
is an abstract class between the object and its
class. The singleton methods are located in the
eigenclass of an object, not at the object
level. As classes are objects, they have an
eigenclass, too.
Tip
Object
class Dog _at__at_count 0 accesses the
eigen-class class ltlt self def count
_at__at_count end end def initialize
_at__at_count 1 end end
Dogs eigenclass
Dog
snoopys eigenclass
snoopy
71OOP exercise
- Write a Ruby script which will
- Contain a Dog class
- Contain a Cat class
- Create dogs and cats
- Allow dogs to run after cats, and only after cats
(raise an error if not) - Help
- Remember that cats dont bark !
72OOP solution 1/3
class Dog attr_reader name this defines a
name method returning _at_name def
initialize(name) _at_name name end ...
def runs_after(cat) raise "not a cat !"
unless cat.is_a? Cat puts "_at_name runs
after cat.name ! Woof ! Woof !" end end
73OOP solution 2/3
class Cat attr_reader name def
initialize(name) _at_name name end ...
def meows puts "_at_name meows ! Meow !
Meow !" end end
74OOP solution 3/3
snoopy Dog.new 'snoopy' felix Cat.new
'felix' snoopy.runs_after felix milou Dog.new
'milou' snoopy.runs_after milou gt
RuntimeError not a cat !
75OOP inheritance
- So we have
- A Dog class
- A Cat class
- They both have
- A name
- Basic methods, like walks, eats, sleeps,
- But they dont shout the same way
- Dogs bark
- Cats meows
76OOP inheritance
class Animal attr_reader name def
initialize(name) _at_name name end def
walks puts "_at_name walks around" end
def sleeps puts "_at_name sleeps...
ZzZZZzZZz..." end end
77OOP inheritance
class Dog lt Animal the Dog class inherits from
Animal def barks puts "_at_name barks !
Woof ! Woof !" end end class Cat lt Animal
the Cat class inherits from Animal def meows
puts "_at_name meows ! Meow ! Meow !" end end
78OOP inheritance
snoopy Dog.new 'snoopy' snoopy.walks gt
snoopy walks around snoopy.sleeps gt snoopy
sleeps... ZzZZZzZZz... snoopy.barks gt snoopy
barks ! Woof ! Woof ! snoopy.class gt
Dog felix Cat.new 'felix' felix.walks gt
felix walks around felix.sleeps gt felix
sleeps... ZzZZZzZZz... felix.meows gt felix
meows ! Meow ! Meow ! felix.is_a? Cat gt
true felix.is_a? Animal gt true
79OOP inheritance
- What if we need a Dog-specific initialize method
? - If we rewrite it, we must still fill _at_name
- We need to call the mother class initialize method
80OOP inheritance
dogs are not vaccinated by default class Dog lt
Animal ... def initialize(name)
_at_vaccinated false super calls the same
method in the mother class end end snoopy
Dog.new "snoopy" gt ltDog0x2f02b00
_at_vaccinatedfalse, _at_name"snoopy"gt
81OOP inheritance
dogs can be vaccinated by default, now class
Dog lt Animal ... def initialize(name,
vaccinated false) _at_vaccinated vaccinated
super end end snoopy Dog.new "snoopy"
gt ArgumentError wrong number of arguments (2
for 1)
82OOP inheritance
dogs can be vaccinated by default, now class
Dog lt Animal ... def initialize(name,
vaccinated false) _at_vaccinated vaccinated
super(name) calls the mother class method,
passing name only end end snoopy Dog.new
"snoopy" gt ltDog0x2ee486c _at_vaccinatedfalse,
_at_name"snoopy"gt
83OOP polymorphism
- Ruby doesnt feature a true polymorphism like
C does - It relies on modules to add capabilities to
classes - You can include one or more modules in a class
- A module can be included in one or more classes
- This is called the mix-in facility
84OOP polymorphism
this module contains the behaviour of a wild
animal module Wild def sleeps puts
"_at_name sleeps under the stars"
end end class Wildcat lt Cat include Wild
includes the Wild module definition here end
85OOP exercise
- Complete the Wild module to describe wild
animals - Use it to define the following classes
- Wildcat
- Wolf
- Help
- No help
86OOP solution 1/4
class Animal attr_reader name def
initialize(name) _at_name name end def
sleeps puts "name sleeps... ZzzZzzZ..."
end end
87OOP solution 2/4
module Wild def hunts puts "name hunts
in the woods" end def sleeps puts "under
the stars," super end end
88OOP solution 3/4
class WildCat lt Animal include Wild def
meows puts "name MEOOOOWWWWSSS !"
end end
89OOP solution 4/4
class Wolf lt Animal include Wild def howls
puts "name howls ahuuuuuuuuu" end
def growls puts "name growls grrrrr..."
end end
90OOP polymorphism
- Modules can be added to specific objects
91OOP polymorphism
snoopy Dog.new "snoopy" gt ltDog0x2ee486c
_at_vaccinatedfalse, _at_name"snoopy"gt snoopy.extend
Wild snoopy definition is extended with Wild
gt ltDog0x2ee486c _at_vaccinatedfalse,
_at_name"snoopy"gt snoopy.sleeps gt under the
stars, snoopy sleeps
92OOP exercise
- Within the Animal class, create a
returns_to_the_wild_life - method, which makes an animal be wild
- Help
- No help
93OOP solution 1/2
class Animal attr_reader name def
initialize(name) _at_name name end def
returns_to_the_wild_life self.extend Wild
puts "_at_name has returned to the wild life"
end end
94OOP solution 2/2
snoopy Dog.new "snoopy" gt ltDog0x2f3c698
_at_name"snoopy"gt snoopy.sleeps gt snoopy
sleeps... ZzZZZzZZz... snoopy.returns_to_the_wild
_life gt snoopy has returned to the wild
life snoopy.sleeps gt under the stars, snoopy
sleeps
95OOP methods visibility
- Ruby provides three levels of visibility for
your methods - Public
- These methods can be called from anywhere
- Protected
- These methods can be called from instances of the
same class only - Private
- These methods can be called only without a
receiver
96OOP methods visibility
class Dog def walks if nothing's specified,
it is public puts "_at_name walks in the
garden" from time to time, dogs find an old
bone they buried unearths_a_bone if rand(2)
1 end private from now, methods are
private def unearths_a_bone puts "_at_name
unearths a bone" end end
97OOP methods visibility
snoopy Dog.new "snoopy" snoopy.walks gt
snoopy walks in the garden snoopy.unearths_a_bone
gt NoMethodError private method
unearths_a_bone' called for ltDog0x2f4412c
_at_name"snoopy"gt snoopy.walks gt snoopy walks
in the garden gt snoopy unearths a bone
98Ruby idioms
98
99Ruby idioms
- Although Ruby borrows much to other languages
- Some is pure-Ruby
- Other is so much used in Ruby it is considered to
be a Ruby idiom
100Ruby idioms blocks
this is a one-line block, enclosed into
brackets puts "This is a block" this is a
multiple lines block do puts "This is a block"
puts "too" end
- Remember that, in Ruby
- Blocks cant exist by themselves
- They must be used or converted into Proc objects
101Ruby idioms blocks
lambda converts your block into a Proc object p
lambda puts "This is a block" proc does
the same job p proc puts "This is a block"
the Proc can turn a block into a new
object p Proc.new do puts "This is a block"
puts "too" end
102Ruby idioms blocks
the call method execute the block associated to
the Proc object p proc puts "Hello world"
p.call gt Hello world blocks can take
arguments they're listed into pipes p proc
name puts "Hello name" p.call "David
gt Hello David p.call "Alexandra gt Hello
Alexandra p proc from, to puts "Hello
to, from says" p.call "Alexandra",
"David" gt Hello David, Alexandra says
103Ruby idioms blocks
- In what blocks are useful ?
- You can separate logic
- You can write generic code
- You can use them with iterators
104Ruby idioms blocks
loop is not a reserved word, but a method loop
do puts "Stop me !" end
105Ruby idioms exercise
- Modify your guess a number Ruby script to
- Replace the while (or until) statement with loop
- Help
- Remember loop is infinite
106Ruby idioms solution
number rand(10) puts "Which number am I
thinking about ?" loop do input gets.to_i
break if input number puts "No, try
again..." end puts "Wonderful, you guessed it"
107Ruby idioms other solution
number rand(10) puts "Which number am I
thinking about ?" begin loop do input
gets.to_i raise "found !" if input number
puts "No, try again..." end rescue Exception
gt e puts "Wonderful, you guessed it" if
e.message "found !" end
108Ruby idioms iterators
- Iterator is one of the Design Patterns
- Basically, it is a mechanism which iterates over
a collection - Theyre used everywhere in Ruby
- Theyre the prefered way of writing code
109Ruby idioms iterators
the most common use of an iterator in Ruby is
the Arrayeach method 1, 2, 3, 4 .each do i
puts i end
- You can read it like this
- each is a method of the Array class
- Which takes a block as argument
- Which passes each element of the array to this
block and executes it - Or like this
- each is an iterator method for arrays
110Ruby idioms iterators
you don't write this developers java gt
10, ruby gt 15, smalltalk gt 3 languages
developers.keys i 0 imax languages.size -
1 while i lt imax language languagesi
puts "developerslanguage people are using
language" i 1 end
111Ruby idioms iterators
buts this developers java gt 10, ruby gt
15, smalltalk gt 3 developers.each_pair do
language, enthusiasts puts "enthusiasts
people are using language" end
112Ruby idioms iterators
you might not read this for i in 1..5 notice
the only for statement you'll see today puts
"counting... i" end
113Ruby idioms iterators
but this (1..5).each do i puts "counting...
i" end or, even better, this 5.times do
i puts "counting... i 1" end this is
basically the same thing, but Rubyists use the
iterator form
114Ruby idioms iterators
you don't write this f File.open('tempfile.txt
') unless f.nil? lines f.read.split i 0
imax lines.size - 1 while i lt imax puts
"gt linesi" i 1 end f.close end
115Ruby idioms iterators
but this File.open('tempfile.txt') do file
f.each_line do line puts "gt line"
end end
116Ruby idioms yield
- The execution of a block passed to a method is
not limited - to Rubys built-in classes
- You can write your own too
117Ruby idioms yield
yield executes the block given to the
method def run yield end run do puts "Hello
world" end gt Hello world
118Dynamic features
118
119Dynamic features
- Ruby is a dynamic language
- Most of your code is evaluated at execution time
- Nothings really locked
120Dynamic features method_missing
class Dog def initialize(name) _at_name
name end end snoopy Dog.new
"snoopy" snoopy.sleeps gt NoMethodError
undefined method sleeps' for ltDog0x2f14b34
_at_name"snoopy"gt
121Dynamic features method_missing
class Dog ... def method_missing(name,
args) puts "called missing method name"
end end snoopy Dog.new "snoopy" snoopy.sleeps
gt called missing method sleeps no
exception raised
122Dynamic features method_missing
class Dog ... def method_missing(action,
args) puts "_at_name action.to_s.gsub('_',
' ')" end end snoopy Dog.new
"snoopy" snoopy.walks gt snoopy
walks snoopy.plays_football gt snoopy plays
football snoopy.is_in_his_kennel gt snoopy is
in his kennel
123Dynamic features method_missing
class Dog ... def method_missing(action,
args) puts "method missing ! defining the
method" self.class.send define_method,
action do puts "_at_name action.to_s.gsub(
'_', ' ')" end self.send(action)
end end
124Dynamic features method_missing
snoopy Dog.new "snoopy" snoopy.makes_charlie_br
own_go_mad gt method_missing ! defining the
method gt snoopy makes charlie brown go
mad snoopy.makes_charlie_brown_go_mad gt
snoopy makes charlie brown go mad
125Dynamic features exercise
- Create a new Dog class which allows dynamically
dogs to - Walk (in the garden, in the street, )
- Play (football, with Charlie Brown, )
- Eat (their dogfood, the cake mum just baked, )
- Sleep (in the garage, in their kennel, )
- Help
- Regular expressions should help you
126Dynamic features solution 1/2
class Dog def initialize(name) _at_name name
end def method_missing(name, args) case
name.to_s when /((?walks)(?plays)(?eat
s)(?sleeps))(?_(.))/ puts "_at_name
1 2.to_s.gsub('_', ' ')" else
puts dogs don't do that" end end end
127Dynamic features solution 2/2
snoopy Dog.new "snoopy" snoopy.walks_in_the_gar
den gt snoopy walks in the garden snoopy.plays_b
aseball gt snoopy plays baseball snoopy.sleeps
gt snoopy sleeps snoopy.eats_his_daily_meal
gt snoopy eats his daily meal snoopy.goes_to_the_
cinema gt dogs don't do that snoopy.drives_a_car
gt dogs don't do that
128Dynamic features eval
- Like most interpreted languages, Ruby can
- Evaluate text as code
- Evaluate blocks
- It can do these in different contexts
129Dynamic features eval
eval "(3 2) 4 gt 20 a dummy echo
service eval "puts \"echo gets\"" you could
write this, for example eval "obj
klass.new" but promise never to write that
! eval "method(params)"
130Dynamic features exercise
- Create a method which
- Takes three parameters an operator and two
operands - Displays the computed result
- Help
- No help
131Dynamic features solution
def calc(operand1, operator, operand2) begin
eval "operand1 operator operand2"
rescue ZeroDivisionError puts "you can't
divide by 0" rescue TypeError puts "did you
provide a number ?" end end calc 1, '',
2 gt 3 calc 9, '/', 0 gt you can't
divide by 0
132Dynamic features eval
class_eval evaluates code in the class
context Cat.class_eval "def meows puts \"Meow !
Meow !\" end" garfield Cat.new
"garfield" garfield.instance_eval do runs
this block in garfield's context sleeps eats
sleeps meows eats end
133Dynamic features exercise
- Add a configure_new method to your Animal class
which - Creates a new instance
- Executes the block given in its context, if a
block is supplied - Returns the new object
- Help
- No help
134Dynamic features solution 1/2
class Animal def self.configure_new(block)
new_animal self.new new_animal.instance_eva
l(block) unless block.nil? new_animal
end ... end
135Dynamic features solution 2/2
snoopy Animal.configure_new do "configuring"
snoopy _at_name "snoopy" _at_owner "charlie
brown" get_vaccinated end garfield
Animal.configure_new do "configuring" garfield
_at_name "garfield" _at_owner "jon" extends
Lazyness end
136Dynamic features introspection
- Ruby is capable of introspection
- Ruby is a reflexive language
- This means that
- You can query the objects
- You can modify them
- You can create new objects (classes, methods,
objects) - You can do all this at runtime
137Dynamic features introspection
obj Array.new obj.class returns Array, the
class, not the string "Array" obj.class.include
Extensions includes a module in the
object class obj.class.instance_methods
lists the object class instance
methods obj.methods lists the object methods
(may differ from the line above) executes all
the methods starting with "on_connect_do_" obj.met
hods.grep(/on_connect_do_/).each do method
obj.send method end
138Dynamic features extending Ruby
- Definitions are not locked you can re-open
them to - Add functionalities
- Re-define behaviours
- This applies to
- Modules, classes and methods you write
- Modules, classes and methods bundled with Ruby
139Dynamic features extending Ruby
class Dog defines a new class def
initialize(name) _at_name name
end end class Dog re-opens the Dog class
definition attr_reader name end snoopy
Dog.new "snoopy" snoopy.name gt snoopy
140Dynamic features extending Ruby
class Dog attr_reader name end class Dog
redefines the name method def name puts
"this dog's called _at_name" end end snoopy.nam
e gt this dog's called snoopy
141Dynamic features extending Ruby
re-opens the Array class definition class
Array alias how_many_items_are_in?
size end arr Array.new(rand(40),
7) arr.how_many_items_are_in? gt may vary
142Dynamic features extending Ruby
re-opens the String class definition class
String def has_vowels? return
!self.scan(/aeiouy/).empty?
end end "rbc".has_vowels? gt
false "dexia".has_vowels? gt true
143Dynamic features exercise
- Extends the Fixnum class to
- Add an odd? method
- Add an even? method
- Help
- No help
144Dynamic features solution
class Fixnum def odd? self 2 1 end
def even? !self.odd? end end 1.odd?
gt true 1.even? gt false 2.even? gt
true
145Dynamic features executed defs
- Definitions are executed, this means
- You can decide setup things at runtime
- Re-define behaviours
146Dynamic features executed defs
Ruby source file animal.rb class Animal
puts "defining the Animal class" ... end C\
ruby animal.rb defining the Animal class C\
147Dynamic features executed defs
MAX_PARAMS 16 class CollectionOfParameters
(1..MAX_PARAMS).each do i attr_reader
"param_i".to_sym creates MAX_PARAMS
methods end end obj CollectionOfParameters.ne
w obj.methods.grep(/param_\d/).size
MAX_PARAMS gt true
148Dynamic features executed defs
class PeriodicTask you don't write this
def save_system_logs if RUBY_PLATFORM
/win32/ performs the operation on MS
Windows systems else performs the
operation on UNIX systems end end
... end
149Dynamic features executed defs
class PeriodicTask but this if
RUBY_PLATFORM /win32/ def
save_system_logs performs the operation
on MS Windows systems end else def
save_system_logs performs the operation
on UNIX systems end end ... end
150Dynamic features executed defs
class Configuration Another platform-dependent
class case RUBY_PLATFORM when /linux/,
/bsd/, /darwin/ def initialize(params)
... end when /win32/
include ProjectExtensionsSpecificWin32
else raise UnknownOperatingSystemError,
"Unknown operating system" end end
151Standard tools
151
152Standard tools
- Ruby comes along with standard tools
- An interactive interpreter irb
- A documentation management tool rdoc
- A third-party code management tool gem
153Standard tools ri
- ri allows you to query the documentation
- to display the documentation, if it exists, just
type - ri classinstance_method
- ri class.class_method
154Standard tools ri
155Standard tools rdoc
- rdoc parses your Ruby code so that comments
- At the beginning of the files
- Before the classes
- Before the modules
- Before the methods
- are turned into HTML documentation for the given
code -
- it features some tags to skip lines and formats
the output
156Standard tools rdoc
This class describes dogs as they are in our
world class Dog this comment won't be used by
rdoc Makes the ltbrgtdoglt/brgt run after
ltttgta cat, and only a ltttgtcatlt/ttgt -- this
line won't be used too, so you can write secret
things here this comment will be used
by rdoc def runs_after(cat) puts "_at_name
runs after cat.name ! Woof ! Woof !" end end
157Standard tools exercise
- Test the rdoc command against the various Ruby
scripts - you wrote today
158Standard tools gem
- gem allows you to manage additional Ruby code
- It features many commands to
- List the gems installed on the computer
- Install new gems (from local .gem files or from
remote locations) - Update installed gems
- Remove gems (or just their older versions)
- And so on
- Most of Ruby applications and libraries are
distributed - as gems
159Standard tools gem
You can browse your gems documentation. The gem
command generates the rdoc documentation when it
installs new gems. To access it, just run the
gem_server command in a terminal, and connect
your favorite Web browser to http//localhost8808
.
Tip
160Bookshelf references
160
161Bookshelf references
- Programming Ruby The Pragmatic Programmers'
Guide - By Dave Thomas, with Chad Fowler Andy Hunt
- Second edition
- The Pragmatic Programmers
- 864 pages
- ISBN 978-0-974-51405-5
162Bookshelf references
- The Ruby Way
- By Hal Fulton
- Second edition
- Addison-Wesley
- 888 pages
- ISBN 978-0-672-32884-8
163Bookshelf references
- Design Patterns in Ruby
- By Russ Olsen
- First edition
- Addison-Wesley
- 384 pages
- ISBN 978-0-321-49045-2
164Online references
164
165Online references
- The official website, Ruby Lang
- http//www.ruby-lang.org/en/
- The documentation website, Ruby Doc
- http//ruby-doc.org/
- The online version of Programming Ruby
- http//www.ruby-doc.org/docs/ProgrammingRuby/
166Online references
- The official mailing lists (talk_at_, core_at_, doc_at_,
) - http//www.ruby-lang.org/en/community/mailing-list
s/ - Ruby on IRC
- ruby-lang _at_ irc.freenode.net
167_END_
167