11. • Write some code to ask a user to input a
number. Take the number multiply it by
10 and display it back to the user
• Find a method to capitalize a string
• Check the class of 1. (using the .class
method) then find a method to check if
the number is even
Exercises
15. String.method.count
# Lots of helpful methods!
"Ruby" * 4
# "RubyRubyRubyRuby"
"Ruby" + " " + "Ruby"
# "Ruby Ruby"
a = "I don’t know Ruby"
a*"don’t"+ = "do"
# "I do know Ruby"
String
16. number_of_girls = 4
number_of_boys = 6
puts "number of girls #{number_of_girls}"
puts "number of boys #{number_of_boys}"
puts "number of people
#{number_of_boys + number_of_girls}"
Interpolation
21. h = {'France' => 'Paris', 'Ireland' => 'Dublin' }
h = {France: 'Paris', Ireland: 'Dublin' }
h[:France]
# 'Paris‘
h[:Italy] = 'Rome'
# h = {France: 'Paris', Ireland: 'Dublin', Italy:
# 'Rome' }
h.each {|k,v| puts "key: #{k} t value: #{v}"}
h.any? { |k,v| v == 'Rome' }
Hashes
22. (1..5).each{|v| p v}
# 1,2,3,4,5
(1…5).each{|v| p v}
# 1,2,3,4
(10..20).include?(19) # true
(2..5).end # 5
("aa".."ae").each{|v| p v}
# "aa","ab","ac","ad","ae"
Ranges
23. def get_values; [1,2,3,4]; end;
first, _, _, last = get_values
# first = 1, last = 4
a, *b, c = get_values
# a = 1, b = [2,3],c = 4
r = (0..5)
a = [1,2,*r]
# a = [1,2,0,1,2,3,4,5]
Splat Operator
24. •
•
Separate an array [1,2,3,4] into 2 variables
one holding the head of the array (i.e 1) and
the other the rest of the array [2,3,4]
Create a hash of months and days in a month
e.g. {January: 31, ..}. For each month print out
the month name and number of days. Then
print out totals days in year by summing the
hashes values
Exercises
26. if mark > 75
report = "great"
elsif mark > 50
report = "good"
else
report = "needs work"
end
report =
if mark > 75 then
"great"
elsif mark > 50 then
"good"
else
"needs work"
end
if else
29. mark = 42 && mark * 2
# translates to mark = (42 && mark) * 2
mark = 42 and mark * 2
# returns 84
post = Posts.locate(post_id) and post.publish
# publishes post if it is located
if engine.cut_out?
engine.restart or enable_emergency_power
end
and / or
30. grade = case mark
when 90..100
"A"
when 70..89
"B"
when 60..69
"C"
when 50..59
"D"
when 40..49
"E"
else
"F"
end
case unit
when String
puts "A String!"
when TrueClass
puts "So True!"
when FalseClass
puts "So False!"
end
case
31. while count < max
puts "Inside the loop. count = #{count}"
count +=1
end
puts "count = #{count += 1}" while count < max
while
32. until count > max
puts "Inside the loop. count = #{count}"
count +=1
end
array = [1,2,3,4,5,6,7]
array.pop until array.length < 3
until
33. begin
puts "Inside the loop. count = #{count}"
count +=1
end while count < max
looping block
34. for count in (1..10)
puts "Inside the loop: count = #{count}"
end
for
35. animals = {cat: "meow ", cow: "moo "}
animals.each do |k,v|
puts "The #{k} goes #{v}"
end
animals = {cat: "meow ", cow: "moo "}
animals.each {|k,v| puts "The #{k} goes #{v} "}
iterators
36. magic_number = 5; found = false; i = 0; input = 0;
while i < 3
print "Please enter a number between 1 and 10: "
input = gets.to_i
unless input.between?(1,10)
print "invalid number"; redo
end
if input == magic_number
found = true; break
end
i += 1
end
found ? put "found! " : put " bad luck "
flow control
37. def display_content(name)
f = File.open(name, 'r')
line_num=0
# raise 'A test exception.'
f.each {|line| print "#{line_num += 1} #{line}"}
rescue Exception => e
puts "ooops"; puts e.message; puts e.backtrace
else
puts "nSuccessfully displayed!"
ensure
if f then f.close; puts "file safely closed"; end
end
exception handling
38. def get_patients()
patients = API.request("/patients")
rescue RuntimeError => e
attempts ||= 0
attempts += 1
if attempts < 3
puts e.message + ". Retrying request. “
retry
else
puts "Failed to retrieve patients"
raise
end
end
exception handling
39. •
•
•
•
Write some conditional logic to capitalize a
string if it is not in uppercase
Print out your name 10 times
Print the string “This is sentence number 1”
where the number 1 changes from 1 to 10
Write a case statements which outputs
“Integer” if the variable is an integer, “Float” if
it is a floating point number or else “don’t
know!”
Exercises
50. class Vehicle
class Vehicle
def crash()
explode
end
def crash()
explode
end
private
def explode()
puts "Boom!"
end
end
def explode()
puts "Boom!"
end
private :explode
end
Method Visibility
51. class SuperCar < Vehicle
def explode()
puts "Massive Boom!"
end
end
Method Visibility
52. result = class Test
answer = 7+5
puts " Calculating in class: " + answer.to_s
answer
end
puts "Output of the class: " + result.to_s
Executable
53. class Rocket
….
end
r = Rocket.new
class Rocket
def land()
puts "Back on Earth"
end
end
r.land
Open Classes
55. a = "abc"
b=a
c = "abc"
a.equal?(b)
# true
a.equal?(c)
# false
a == b
# true
a == c
# true
Equality
56. •
•
•
•
•
•
Create a class to represent a Computer
Create an instance of the Computer called
computer
Add a starting_up method
Create a class WindowsComputer which
inherits from Computer
Create an instance of the WindowsComputer
called wcomputer and call starting_up on it
Alter WindowsComputer to allow the user to
set a name value when they create an
instance. Allow the user to set and get the
name attribute
Exercises
61. class Meteor
attr_accessor :speed
def initialize()
@speed = 0
end
def +(amt)
@speed += amt
end
def -(amt)
@speed > amt ? (@speed -= amt) : (@speed = 0)
end
end
Operators
62. class Roman
def self.method_missing name, *args
roman = name.to_s
roman.gsub!("IV", "IIII")
roman.gsub!("IX", "VIIII")
roman.gsub!("XL", "XXXX")
roman.gsub!("XC", "LXXXX")
(roman.count("I") +
roman.count("V") * 5 +
roman.count("X") * 10 +
roman.count("L") * 50 +
roman.count("C") * 100)
end
end
Method
Missing
64. •
•
•
•
•
•
Alter the WindowsComputer class you created in the
last exercise to make the name parameter optional
Try creating an instance with and without a name
value
Add a mandatory attribute called owner to the class
and alter initialize to set it.
Try creating a new instance with no, 1 and 2
parameter values. What happens?
add a method display_details to output the name
and owner of the machine and try calling it using
__send__
now make display_details private and try calling it
directly and using __send__. Notice anything odd?
Exercises
66. def block_example
puts 'Optional block example.'
if block_given?
yield "Heather"
else
puts 'No block. Very Empty'
end
puts 'End of example'
end
Blocks
67. def with_timing
start = Time.now
if block_given?
yield
puts 'Time taken:
#{Time.now - start}'
end
end
Blocks
68. def add_numbers(x, y)
x+y
end
alter the above method to accept a block and
execute it if one is supplied. Call it with a block to
provide debug i.e. displaying the method name
and values passed
Exercises
72. require "minitest/autorun"
describe Employee do
before do
@employee = Employee.new
end
describe "when asked for an employer" do
it "must provide one" do
@employee.employer.must_equal "Kainos"
end
end
end
MiniTest
73. # bowling_spec.rb
require 'bowling'
describe Bowling, "#score" do
it "returns 0 for all gutter game" do
bowling = Bowling.new
20.times { bowling.hit(0) }
bowling.score.should eq(0)
end
end
RSpec
74. # division.feature
Feature: Division
In order to avoid silly mistakes
Cashiers must be able to calculate a fraction
Scenario: Regular numbers
* I have entered 3 into the calculator
* I have entered 2 into the calculator
* I press divide
* the result should be 1.5 on the screen
Cucumber
75. #calculator_steps.rb
Before do
@calc = Calculator.new
end
Given /I have entered (d+) into the calculator/ do
|n|
@calc.push n.to_i
end
When /I press (w+)/ do |op|
@result = @calc.send op
end
Cucumber
76. Want to Learn More?
Codecademy
http://www.codecademy.com/tracks/ruby
CodeSchool
https://www.codeschool.com/paths/ruby
Seven Languages in Seven Weeks
pragprog.com/book/btlang/seven-languages-in-seven-weeks
77. Want to Learn More?
Programming Ruby
pragprog.com/book/ruby/programming-ruby
First edition available for free online at
http://ruby-doc.com/docs/ProgrammingRuby/
Ruby Koans
http://rubykoans.com
Pluralsight
sees everything as an object even things other languages represent as primitivesa = 4.5a.classString.public_methods.sortString.superclass
b = [] b.empty? c = “” c.empty? c.nil?
Dangerous a = “abcde” a.upcase a a.upcase! a
readonly
used a lot in Ruby. Cleaner and more performant than concatenation. Doesn’t require creation of multiple strings
Global unique and immutable, good substitute for string where like label e.g. hash keys,
can also + to join and *
Close to 50 methods v powerful
also includes enumerable module
can also + to join and *
works with any class with implements to_a method
operators to control flow. Chaining events. and if this is true then do this. or like a fallback try this or try this
tend to use each construct instead. Use with ranges
tend to use each construct instead. Use with ranges
break: exits out of loop. In this case because we’ve found number, redo repeats iteration without re-evaluating the loop conditionnext: starts next iteration of loop without completing the current loop
rescue: handling if an exception occures, else: only executed if no error occurred, ensure: always executed…tidying up!
making a call to web service to retrieve list of patients. Sometimes it temp is unavailable, allowed 3 attempts before failingnote conditional initialization of attempts
Overridden method, same initialize method, same attributes
Overridden method, same initialize method, same attributes
What method it understands is key not it’s type or parents
2 v different classes both with a quack method
Overridden method, same initialize method, same attributes
instance variables/attributes private by defaultinstance methods public by defaultprivate / protectedprivate can be called by subclasses. can’t be called with explicit object receiverprotected objs of sames class, obj with same ancestor if defined in the ancestor
If you override method you need to explicitly set visibiliy again e.g. overridden explode method is public
real uses are attr_accessor, private etc.http://ruby-doc.org/core-1.9.3/Module.html
In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.
extend or modify the run-time code of dynamic languages without altering the original source code. (third party libs)Power use wisely. Just becase you can do something doesn’t mean you should do it. Unexpected behaviour, assumptions made in how you change it may not be valid as versions of class change
Can’t do it! Same method name but different param lists. instead can have optional paramsdefault values, method calls, conditional logic. calculated at the point of method call
Can override operators. use sparingly where it makes code more readable. can cause unexpected behaviour for user and be cryptic to read
Methods sent as messages to object instance. Receives it and looks to see if method exists anywhere in hierarchy if it does calls method with provided parameters
Piece of code between do and end (multiline) or { single line} which can be passed as an arg to certain methods
Avoid boiler plate code like timing, transactions
TDD write test first and then just enough code to make it pass then repeatBDD specialised version of TDD where tests are defined in a format that is meaningful to the business, in terms of domain