SlideShare uma empresa Scribd logo
1 de 75
Ruby Masterclass
     Kerry Buckley
     16 June 2011
History

• Created in 1993
• First public release Christmas 1995
• ‘Pickaxe’ book first published in 2001
• Ruby on Rails released in 2005
Philosophy

“I wanted a scripting language that was
more powerful than Perl, and more object-
oriented than Python. That’s why I decided
to design my own language”
               — Yukihiro ‘Matz’ Matsumoto
Philosophy
“I hope to see Ruby help every
programmer in the world to be productive,
and to enjoy programming, and to be
happy. That is the primary purpose of
Ruby language.”
              — Yukihiro ‘Matz’ Matsumoto
Characteristics
• Strongly but dynamically typed
• Interpreted
• Object-oriented
• …but can be procedural
• …or even (mostly) functional
• Concise but readable
Applications
• Web apps
• Shell scripting
• Build automation
• Deployment automation
• ‘Glue’ code
Culture
• Permissive open source (MIT)
• Favour simplicity
• Agile (especially TDD)
• Mac/Linux
• Fast-moving
• Fun!
Basic syntax
puts "hello world"
Variables

$global_variable = 123

@@class_variable = "hello"

@instance_variable = [1, 2, 3]

local_variable = true
Built-in types
42
1.5
"string"
:symbol
[1, 2, "foo"]
{1 => "one", 2 => "two"}
(1..10)
/^foo.*$/
true
false
nil
Classes & methods
class MyClass
 def initialize number
   @number = number
 end

 def double
  @number * 2
 end

 def hello(name = "world")
  puts "Hello #{name.capitalize}"
 end
end

my_object = MyClass.new(2)
puts my_object.double #=> prints "4"
my_object.hello       #=> prints "hello World"
my_object.hello "kerry" #=> prints "hello Kerry"
Accessors
Accessors
class Rectangle
 attr_accessor :x
 attr_reader :y

 def initialize x, y
  @x, @y = x, y
 end
end
Accessors
class Rectangle
 attr_accessor :x
 attr_reader :y

 def initialize x, y
  @x, @y = x, y
 end
end

rect = Rectangle.new 2, 4
rect.x #=> 2
rect.y #=> 4
Accessors
class Rectangle
 attr_accessor :x
 attr_reader :y

 def initialize x, y
  @x, @y = x, y
 end
end

rect = Rectangle.new 2, 4
rect.x #=> 2
rect.y #=> 4

rect.x = 3
rect.x #=> 3
Accessors
class Rectangle
 attr_accessor :x
 attr_reader :y

 def initialize x, y
  @x, @y = x, y
 end
end

rect = Rectangle.new 2, 4
rect.x #=> 2
rect.y #=> 4

rect.x = 3
rect.x #=> 3

rect.y = 3 #=> NoMethodError
if, else and unless
if, else and unless
if a == b
  puts "The same"
elsif a < b
  puts "A is lower"
else
  puts "A is higher"
end
if, else and unless
if a == b
  puts "The same"
elsif a < b
  puts "A is lower"
else
  puts "A is higher"
end

unless finished?
 do_stuff
end
if, else and unless
if a == b
  puts "The same"
elsif a < b
  puts "A is lower"
else
  puts "A is higher"
end

unless finished?
 do_stuff
end

raise "Oops" if result.nil?
case
case foo
when nil
 puts "foo is nil"
when /^a/i
 puts "foo begins with an 'A'"
when String
 puts "foo is a string"
when (1..10)
 puts "foo is in the range 1-10"
else
 puts "foo is something else"
end
Loops

for a in (1..10) do
 puts a
end

b=0
while b <= 10
 puts b
 b += 1
end
Including other code

• load
• require
• Rubygems
Exercise 1
 Playing with irb
Everything is an object

42.class       #=> Fixnum

Fixnum.class      #=> Class

nil.class      #=> NilClass

true.class      #=> TrueClass

method(:puts).class #=> Method
Duck typing
class Duck
  def quack
    "Quack"
  end
end

class Dog
  def quack
    "Woof"
  end
end

for animal in [Duck.new, Dog.new] do
  puts animal.quack
end

"a string".quack #=> NoMethodError
Dynamic typing

foo = 123

foo.class #=> Fixnum

foo = "foo"

foo.class #=> String
Open classes

puts 123 #=> "123"

class Fixnum
 def to_s
   "Not telling you!"
 end
end

puts 123 #=> "Not telling you!"
Open classes

puts 123 #=> "123"

class Fixnum
 def to_s
   "Not telling you!"
 end
end

puts 123 #=> "Not telling you!"



         You probably don’t want to do this.
Aliasing methods
require "fileutils"

class << FileUtils
 def rm_with_prompt *files
   print "Are you sure you want to delete #{files}? "
   response = gets.chomp.downcase
   return unless %w{yes y}.include?(response)
   rm_without_prompt *files
 end

 alias_method :rm_without_prompt, :rm
 alias_method :rm, :rm_with_prompt
end

FileUtils.rm "a_file"
Blocks
Blocks
begin
 puts "This is a block, but it's not much use"
end
Blocks
begin
 puts "This is a block, but it's not much use"
end

block = Proc.new do
 puts "Now I'm assigned to a variable"
end

# Nothing printed yet
Blocks
begin
 puts "This is a block, but it's not much use"
end

block = Proc.new do
 puts "Now I'm assigned to a variable"
end

# Nothing printed yet

block.call #=> executes the block
Blocks
begin
 puts "This is a block, but it's not much use"
end

block = Proc.new do
 puts "Now I'm assigned to a variable"
end

# Nothing printed yet

block.call #=> executes the block

Proc.new { puts "curly brackets work too" }
Blocks with arguments

block = Proc.new do |arg|
 puts "You called me with #{arg.inspect}"
end

block.call("foo") #=> You called me with "foo"
Explicit block args
def n_times(n, &block)
 puts "starting..."
 n.times { block.call }
 puts "done."
end

n_times(3) do
 puts "hello"
end

#=>   starting...
#=>   hello
#=>   hello
#=>   hello
#=>   done.
Implicit block args
def n_times(n)
 puts "starting..."
 n.times { yield }
 puts "done."
end

n_times(3) do
 puts "hello"
end

#=>   starting...
#=>   hello
#=>   hello
#=>   hello
#=>   done.
File IO with blocks
File IO with blocks

file = File.open "logfile", "a"
file.puts "log message"
file.close
File IO with blocks

file = File.open "logfile", "a"
file.puts "log message"
file.close

File.open "logfile", "a" do |file|
 file.puts "log message"
end
Modules
Modules
module InfoDisplay
 def display_info
  puts "Class: #{self.class}, ID: #{object_id}"
 end
end

class SomeClass
 include InfoDisplay
end

SomeClass.new.display_info
 #=> "Class: SomeClass, ID: 2159853660"
Modules
module InfoDisplay
 def display_info
  puts "Class: #{self.class}, ID: #{object_id}"
 end
end

class SomeClass
 include InfoDisplay
end

SomeClass.new.display_info
 #=> "Class: SomeClass, ID: 2159853660"

String.send :include, InfoDisplay

"foo".display_info #=> "Class: String, ID: 2159853520"
Modules: Enumerable
class Words
 include Enumerable

 def initialize string
  @words = string.split
 end

 def each
  @words.each {|word| yield word }
 end
end

words = Words.new("The quick brown fox")
puts words.first             #=> "The"
puts words.count             #=> 4
p words.select{|w| w.length == 3 } # => ["The", "fox"]
Exercise 2
Working with Enumerable
Metaprogramming

• Programs writing programs
• Modify behaviour at runtime
• Generate code
• Respond dynamically to messages
Evaluating code
Evaluating code
code = 'puts "hello"'

eval code #=> "hello"
Evaluating code
code = 'puts "hello"'

eval code #=> "hello"

foo = "Ruby"

foo.instance_eval do
 def hello
  puts "Hello, I'm #{self}"
 end
end

foo.hello #=> "Hello, I'm Ruby"
Dynamic calling
Dynamic calling

foo = "Hello"
foo.upcase    #=> "HELLO"
foo.send :upcase #=> "HELLO"
Dynamic calling

foo = "Hello"
foo.upcase    #=> "HELLO"
foo.send :upcase #=> "HELLO"

method = [:upcase, :downcase][rand(2)]
foo.send method #=> Randomly "HELLO" or "hello"
Dynamic calling

foo = "Hello"
foo.upcase    #=> "HELLO"
foo.send :upcase #=> "HELLO"

method = [:upcase, :downcase][rand(2)]
foo.send method #=> Randomly "HELLO" or "hello"

bar = 2
bar.send :+, 2 #=> 4
Dynamic response

class Foo
 def method_missing name, *args
   puts "You called #{name} with #{args.inspect}"
 end
end

Foo.new.bar(1, "hello")
 #=> You called bar with [1, "hello"]
Exercise 3
 Metaprogramming
Rake
require "erb"
require "rake/clean"
CLOBBER.include("output/*")

OUTPUT_FILE = "output/README.txt"
TEMPLATE_FILE = "templates/README.txt.erb"

desc "Build the README file from the template"
file OUTPUT_FILE => TEMPLATE_FILE do
 template = File.read(TEMPLATE_FILE)
 File.open(OUTPUT_FILE, "w") do |f|
   output = ERB.new(template).result(binding)
   f.write output
 end
end

task :default => [OUTPUT_FILE]
Exercise 4
   Rake
Web frameworks




  and many more…
Web servers
Mongrel

                        CGI




              Webrick
Before Rack
Before Rack
Before Rack
Before Rack
Before Rack
With Rack


Rack-compliant interface
A rack app

require "rack"

class HelloWorld
 def call env
   [200, {"Content-Type" => "text/plain"},
    StringIO.new("Hello world")]
 end
end

run HelloWorld.new
Exercise 5
   Rack
Shell scripting
#!/usr/bin/env ruby

require "fileutils"
include FileUtils

ARGV.each do |file|
 cp file, "#{file}.bak"
end

system "service httpd restart"
 #=> returns true or false

users = `users`.split
Testing

• Test/Unit & SimpleTest
• RSpec
• Cucumber
• Capybara
JRuby
• Another implementation of Ruby
• Written in Java
• Comparable or better performance
• Use Java libraries from Ruby code
• Deploy Rails apps as WAR files
Calling Java from Ruby

require 'java'

frame = javax.swing.JFrame.new "Window"
label = javax.swing.JLabel.new "Hello"

frame.getContentPane.add label
frame.setDefaultCloseOperation(
   javax.swing.JFrame::EXIT_ON_CLOSE)
frame.pack
frame.setVisible true
Calling Ruby from Java
import org.jruby.embed.ScriptingContainer;

public class HelloWorld {

    private HelloWorld() {
      ScriptingContainer c = new ScriptingContainer();
      c.runScriptlet("puts "Hello World!"");
    }

    public static void main(String[] args) {
      new HelloWorld();
    }
}
while Time.now.hour < 17
 audience_suggestions.pop.discuss
end

go :home

Mais conteúdo relacionado

Mais procurados

(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Rolessartak
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScriptStalin Thangaraj
 
Javascript the New Parts v2
Javascript the New Parts v2Javascript the New Parts v2
Javascript the New Parts v2Federico Galassi
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Introducing ruby on rails
Introducing ruby on railsIntroducing ruby on rails
Introducing ruby on railsPriceen
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackUAnshu Prateek
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Slides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammersSlides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammersGiovanni924
 
Haxe: What Makes It Cool
Haxe: What Makes It CoolHaxe: What Makes It Cool
Haxe: What Makes It CooleddieSullivan
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentationadamcookeuk
 

Mais procurados (20)

(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Roles
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScript
 
Javascript the New Parts v2
Javascript the New Parts v2Javascript the New Parts v2
Javascript the New Parts v2
 
Effective ES6
Effective ES6Effective ES6
Effective ES6
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Introducing ruby on rails
Introducing ruby on railsIntroducing ruby on rails
Introducing ruby on rails
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Php introduction
Php introductionPhp introduction
Php introduction
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackU
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
 
Slides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammersSlides chapter3part1 ruby-forjavaprogrammers
Slides chapter3part1 ruby-forjavaprogrammers
 
Haxe: What Makes It Cool
Haxe: What Makes It CoolHaxe: What Makes It Cool
Haxe: What Makes It Cool
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 

Destaque

Slideshare V1 1226988038533013 8
Slideshare V1 1226988038533013 8Slideshare V1 1226988038533013 8
Slideshare V1 1226988038533013 8Mario Charlin
 
The state of the Twittersphere, February 2011
The state of the Twittersphere, February 2011The state of the Twittersphere, February 2011
The state of the Twittersphere, February 2011Kathryn Corrick
 
Atrévete a conocerte: coaching Funds Experience
Atrévete a conocerte: coaching Funds ExperienceAtrévete a conocerte: coaching Funds Experience
Atrévete a conocerte: coaching Funds ExperienceRankia
 
Participación cuidadana
Participación cuidadanaParticipación cuidadana
Participación cuidadanaedparraz
 
Liverpool Science Park Breakfast: social media morning
Liverpool Science Park Breakfast: social media morningLiverpool Science Park Breakfast: social media morning
Liverpool Science Park Breakfast: social media morningKathryn Corrick
 
Digital Britain - Final report
Digital Britain - Final reportDigital Britain - Final report
Digital Britain - Final reportKathryn Corrick
 
A marketers tour of Timeline and Pages
A marketers tour of Timeline and PagesA marketers tour of Timeline and Pages
A marketers tour of Timeline and PagesKathryn Corrick
 
The Impact of Social Media on Society and Democracy
The Impact of Social Media on Society and DemocracyThe Impact of Social Media on Society and Democracy
The Impact of Social Media on Society and DemocracyKathryn Corrick
 

Destaque (8)

Slideshare V1 1226988038533013 8
Slideshare V1 1226988038533013 8Slideshare V1 1226988038533013 8
Slideshare V1 1226988038533013 8
 
The state of the Twittersphere, February 2011
The state of the Twittersphere, February 2011The state of the Twittersphere, February 2011
The state of the Twittersphere, February 2011
 
Atrévete a conocerte: coaching Funds Experience
Atrévete a conocerte: coaching Funds ExperienceAtrévete a conocerte: coaching Funds Experience
Atrévete a conocerte: coaching Funds Experience
 
Participación cuidadana
Participación cuidadanaParticipación cuidadana
Participación cuidadana
 
Liverpool Science Park Breakfast: social media morning
Liverpool Science Park Breakfast: social media morningLiverpool Science Park Breakfast: social media morning
Liverpool Science Park Breakfast: social media morning
 
Digital Britain - Final report
Digital Britain - Final reportDigital Britain - Final report
Digital Britain - Final report
 
A marketers tour of Timeline and Pages
A marketers tour of Timeline and PagesA marketers tour of Timeline and Pages
A marketers tour of Timeline and Pages
 
The Impact of Social Media on Society and Democracy
The Impact of Social Media on Society and DemocracyThe Impact of Social Media on Society and Democracy
The Impact of Social Media on Society and Democracy
 

Semelhante a Ruby

Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Ruby — An introduction
Ruby — An introductionRuby — An introduction
Ruby — An introductionGonçalo Silva
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Wen-Tien Chang
 
Metaprogramming + Ds Ls
Metaprogramming + Ds LsMetaprogramming + Ds Ls
Metaprogramming + Ds LsArrrrCamp
 
SEMAC 2011 - Apresentando Ruby e Ruby on Rails
SEMAC 2011 - Apresentando Ruby e Ruby on RailsSEMAC 2011 - Apresentando Ruby e Ruby on Rails
SEMAC 2011 - Apresentando Ruby e Ruby on RailsFabio Akita
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new thingsDavid Black
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in RubyConFoo
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogrammingjoshbuddy
 

Semelhante a Ruby (20)

Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
Designing Ruby APIs
Designing Ruby APIsDesigning Ruby APIs
Designing Ruby APIs
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Ruby — An introduction
Ruby — An introductionRuby — An introduction
Ruby — An introduction
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介
 
Metaprogramming + Ds Ls
Metaprogramming + Ds LsMetaprogramming + Ds Ls
Metaprogramming + Ds Ls
 
SEMAC 2011 - Apresentando Ruby e Ruby on Rails
SEMAC 2011 - Apresentando Ruby e Ruby on RailsSEMAC 2011 - Apresentando Ruby e Ruby on Rails
SEMAC 2011 - Apresentando Ruby e Ruby on Rails
 
Ruby 2.0
Ruby 2.0Ruby 2.0
Ruby 2.0
 
Language supports it
Language supports itLanguage supports it
Language supports it
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby Basics
 
Rails by example
Rails by exampleRails by example
Rails by example
 

Mais de Kerry Buckley

Testing http calls with Webmock and VCR
Testing http calls with Webmock and VCRTesting http calls with Webmock and VCR
Testing http calls with Webmock and VCRKerry Buckley
 
Ruby nooks & crannies
Ruby nooks & cranniesRuby nooks & crannies
Ruby nooks & cranniesKerry Buckley
 
Javasccript MV* frameworks
Javasccript MV* frameworksJavasccript MV* frameworks
Javasccript MV* frameworksKerry Buckley
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test communityKerry Buckley
 
What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)Kerry Buckley
 
Adastral Park code retreat introduction
Adastral Park code retreat introductionAdastral Park code retreat introduction
Adastral Park code retreat introductionKerry Buckley
 
MongoMapper lightning talk
MongoMapper lightning talkMongoMapper lightning talk
MongoMapper lightning talkKerry Buckley
 
The secret life of bees
The secret life of beesThe secret life of bees
The secret life of beesKerry Buckley
 
Background processing
Background processingBackground processing
Background processingKerry Buckley
 
Katas, Contests and Coding Dojos
Katas, Contests and Coding DojosKatas, Contests and Coding Dojos
Katas, Contests and Coding DojosKerry Buckley
 
Kanban and Iterationless Working
Kanban and Iterationless WorkingKanban and Iterationless Working
Kanban and Iterationless WorkingKerry Buckley
 
Software Development Trends
Software Development TrendsSoftware Development Trends
Software Development TrendsKerry Buckley
 

Mais de Kerry Buckley (20)

Jasmine
JasmineJasmine
Jasmine
 
Testing http calls with Webmock and VCR
Testing http calls with Webmock and VCRTesting http calls with Webmock and VCR
Testing http calls with Webmock and VCR
 
BDD with cucumber
BDD with cucumberBDD with cucumber
BDD with cucumber
 
Ruby nooks & crannies
Ruby nooks & cranniesRuby nooks & crannies
Ruby nooks & crannies
 
TDD refresher
TDD refresherTDD refresher
TDD refresher
 
Javasccript MV* frameworks
Javasccript MV* frameworksJavasccript MV* frameworks
Javasccript MV* frameworks
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)What I learned from Seven Languages in Seven Weeks (IPRUG)
What I learned from Seven Languages in Seven Weeks (IPRUG)
 
Functional ruby
Functional rubyFunctional ruby
Functional ruby
 
Adastral Park code retreat introduction
Adastral Park code retreat introductionAdastral Park code retreat introduction
Adastral Park code retreat introduction
 
MongoMapper lightning talk
MongoMapper lightning talkMongoMapper lightning talk
MongoMapper lightning talk
 
Cloud
CloudCloud
Cloud
 
The secret life of bees
The secret life of beesThe secret life of bees
The secret life of bees
 
Background processing
Background processingBackground processing
Background processing
 
Katas, Contests and Coding Dojos
Katas, Contests and Coding DojosKatas, Contests and Coding Dojos
Katas, Contests and Coding Dojos
 
Rack
RackRack
Rack
 
Doing REST Right
Doing REST RightDoing REST Right
Doing REST Right
 
Kanban and Iterationless Working
Kanban and Iterationless WorkingKanban and Iterationless Working
Kanban and Iterationless Working
 
Software Development Trends
Software Development TrendsSoftware Development Trends
Software Development Trends
 

Último

VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service JamshedpurVIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service JamshedpurSuhani Kapoor
 
Call Girls in Gomti Nagar - 7388211116 - With room Service
Call Girls in Gomti Nagar - 7388211116  - With room ServiceCall Girls in Gomti Nagar - 7388211116  - With room Service
Call Girls in Gomti Nagar - 7388211116 - With room Servicediscovermytutordmt
 
A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMANIlamathiKannappan
 
Eni 2024 1Q Results - 24.04.24 business.
Eni 2024 1Q Results - 24.04.24 business.Eni 2024 1Q Results - 24.04.24 business.
Eni 2024 1Q Results - 24.04.24 business.Eni
 
Vip Dewas Call Girls #9907093804 Contact Number Escorts Service Dewas
Vip Dewas Call Girls #9907093804 Contact Number Escorts Service DewasVip Dewas Call Girls #9907093804 Contact Number Escorts Service Dewas
Vip Dewas Call Girls #9907093804 Contact Number Escorts Service Dewasmakika9823
 
Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...
Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...
Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...Dipal Arora
 
VIP Kolkata Call Girl Howrah 👉 8250192130 Available With Room
VIP Kolkata Call Girl Howrah 👉 8250192130  Available With RoomVIP Kolkata Call Girl Howrah 👉 8250192130  Available With Room
VIP Kolkata Call Girl Howrah 👉 8250192130 Available With Roomdivyansh0kumar0
 
0183760ssssssssssssssssssssssssssss00101011 (27).pdf
0183760ssssssssssssssssssssssssssss00101011 (27).pdf0183760ssssssssssssssssssssssssssss00101011 (27).pdf
0183760ssssssssssssssssssssssssssss00101011 (27).pdfRenandantas16
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communicationskarancommunications
 
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
Keppel Ltd. 1Q 2024 Business Update  Presentation SlidesKeppel Ltd. 1Q 2024 Business Update  Presentation Slides
Keppel Ltd. 1Q 2024 Business Update Presentation SlidesKeppelCorporation
 
RE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman LeechRE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman LeechNewman George Leech
 
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999Tina Ji
 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Neil Kimberley
 
Tech Startup Growth Hacking 101 - Basics on Growth Marketing
Tech Startup Growth Hacking 101  - Basics on Growth MarketingTech Startup Growth Hacking 101  - Basics on Growth Marketing
Tech Startup Growth Hacking 101 - Basics on Growth MarketingShawn Pang
 
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Lviv Startup Club
 
Catalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdf
Catalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdfCatalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdf
Catalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdfOrient Homes
 
Regression analysis: Simple Linear Regression Multiple Linear Regression
Regression analysis:  Simple Linear Regression Multiple Linear RegressionRegression analysis:  Simple Linear Regression Multiple Linear Regression
Regression analysis: Simple Linear Regression Multiple Linear RegressionRavindra Nath Shukla
 
DEPED Work From Home WORKWEEK-PLAN.docx
DEPED Work From Home  WORKWEEK-PLAN.docxDEPED Work From Home  WORKWEEK-PLAN.docx
DEPED Work From Home WORKWEEK-PLAN.docxRodelinaLaud
 
Monte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSMMonte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSMRavindra Nath Shukla
 

Último (20)

VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service JamshedpurVIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
 
KestrelPro Flyer Japan IT Week 2024 (English)
KestrelPro Flyer Japan IT Week 2024 (English)KestrelPro Flyer Japan IT Week 2024 (English)
KestrelPro Flyer Japan IT Week 2024 (English)
 
Call Girls in Gomti Nagar - 7388211116 - With room Service
Call Girls in Gomti Nagar - 7388211116  - With room ServiceCall Girls in Gomti Nagar - 7388211116  - With room Service
Call Girls in Gomti Nagar - 7388211116 - With room Service
 
A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMAN
 
Eni 2024 1Q Results - 24.04.24 business.
Eni 2024 1Q Results - 24.04.24 business.Eni 2024 1Q Results - 24.04.24 business.
Eni 2024 1Q Results - 24.04.24 business.
 
Vip Dewas Call Girls #9907093804 Contact Number Escorts Service Dewas
Vip Dewas Call Girls #9907093804 Contact Number Escorts Service DewasVip Dewas Call Girls #9907093804 Contact Number Escorts Service Dewas
Vip Dewas Call Girls #9907093804 Contact Number Escorts Service Dewas
 
Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...
Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...
Call Girls Navi Mumbai Just Call 9907093804 Top Class Call Girl Service Avail...
 
VIP Kolkata Call Girl Howrah 👉 8250192130 Available With Room
VIP Kolkata Call Girl Howrah 👉 8250192130  Available With RoomVIP Kolkata Call Girl Howrah 👉 8250192130  Available With Room
VIP Kolkata Call Girl Howrah 👉 8250192130 Available With Room
 
0183760ssssssssssssssssssssssssssss00101011 (27).pdf
0183760ssssssssssssssssssssssssssss00101011 (27).pdf0183760ssssssssssssssssssssssssssss00101011 (27).pdf
0183760ssssssssssssssssssssssssssss00101011 (27).pdf
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communications
 
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
Keppel Ltd. 1Q 2024 Business Update  Presentation SlidesKeppel Ltd. 1Q 2024 Business Update  Presentation Slides
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
 
RE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman LeechRE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman Leech
 
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023
 
Tech Startup Growth Hacking 101 - Basics on Growth Marketing
Tech Startup Growth Hacking 101  - Basics on Growth MarketingTech Startup Growth Hacking 101  - Basics on Growth Marketing
Tech Startup Growth Hacking 101 - Basics on Growth Marketing
 
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
 
Catalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdf
Catalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdfCatalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdf
Catalogue ONG NƯỚC uPVC - HDPE DE NHAT.pdf
 
Regression analysis: Simple Linear Regression Multiple Linear Regression
Regression analysis:  Simple Linear Regression Multiple Linear RegressionRegression analysis:  Simple Linear Regression Multiple Linear Regression
Regression analysis: Simple Linear Regression Multiple Linear Regression
 
DEPED Work From Home WORKWEEK-PLAN.docx
DEPED Work From Home  WORKWEEK-PLAN.docxDEPED Work From Home  WORKWEEK-PLAN.docx
DEPED Work From Home WORKWEEK-PLAN.docx
 
Monte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSMMonte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSM
 

Ruby

  • 1. Ruby Masterclass Kerry Buckley 16 June 2011
  • 2. History • Created in 1993 • First public release Christmas 1995 • ‘Pickaxe’ book first published in 2001 • Ruby on Rails released in 2005
  • 3. Philosophy “I wanted a scripting language that was more powerful than Perl, and more object- oriented than Python. That’s why I decided to design my own language” — Yukihiro ‘Matz’ Matsumoto
  • 4. Philosophy “I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.” — Yukihiro ‘Matz’ Matsumoto
  • 5. Characteristics • Strongly but dynamically typed • Interpreted • Object-oriented • …but can be procedural • …or even (mostly) functional • Concise but readable
  • 6. Applications • Web apps • Shell scripting • Build automation • Deployment automation • ‘Glue’ code
  • 7. Culture • Permissive open source (MIT) • Favour simplicity • Agile (especially TDD) • Mac/Linux • Fast-moving • Fun!
  • 10. Variables $global_variable = 123 @@class_variable = "hello" @instance_variable = [1, 2, 3] local_variable = true
  • 11. Built-in types 42 1.5 "string" :symbol [1, 2, "foo"] {1 => "one", 2 => "two"} (1..10) /^foo.*$/ true false nil
  • 12. Classes & methods class MyClass def initialize number @number = number end def double @number * 2 end def hello(name = "world") puts "Hello #{name.capitalize}" end end my_object = MyClass.new(2) puts my_object.double #=> prints "4" my_object.hello #=> prints "hello World" my_object.hello "kerry" #=> prints "hello Kerry"
  • 14. Accessors class Rectangle attr_accessor :x attr_reader :y def initialize x, y @x, @y = x, y end end
  • 15. Accessors class Rectangle attr_accessor :x attr_reader :y def initialize x, y @x, @y = x, y end end rect = Rectangle.new 2, 4 rect.x #=> 2 rect.y #=> 4
  • 16. Accessors class Rectangle attr_accessor :x attr_reader :y def initialize x, y @x, @y = x, y end end rect = Rectangle.new 2, 4 rect.x #=> 2 rect.y #=> 4 rect.x = 3 rect.x #=> 3
  • 17. Accessors class Rectangle attr_accessor :x attr_reader :y def initialize x, y @x, @y = x, y end end rect = Rectangle.new 2, 4 rect.x #=> 2 rect.y #=> 4 rect.x = 3 rect.x #=> 3 rect.y = 3 #=> NoMethodError
  • 18. if, else and unless
  • 19. if, else and unless if a == b puts "The same" elsif a < b puts "A is lower" else puts "A is higher" end
  • 20. if, else and unless if a == b puts "The same" elsif a < b puts "A is lower" else puts "A is higher" end unless finished? do_stuff end
  • 21. if, else and unless if a == b puts "The same" elsif a < b puts "A is lower" else puts "A is higher" end unless finished? do_stuff end raise "Oops" if result.nil?
  • 22. case case foo when nil puts "foo is nil" when /^a/i puts "foo begins with an 'A'" when String puts "foo is a string" when (1..10) puts "foo is in the range 1-10" else puts "foo is something else" end
  • 23. Loops for a in (1..10) do puts a end b=0 while b <= 10 puts b b += 1 end
  • 24. Including other code • load • require • Rubygems
  • 25. Exercise 1 Playing with irb
  • 26. Everything is an object 42.class #=> Fixnum Fixnum.class #=> Class nil.class #=> NilClass true.class #=> TrueClass method(:puts).class #=> Method
  • 27. Duck typing class Duck def quack "Quack" end end class Dog def quack "Woof" end end for animal in [Duck.new, Dog.new] do puts animal.quack end "a string".quack #=> NoMethodError
  • 28. Dynamic typing foo = 123 foo.class #=> Fixnum foo = "foo" foo.class #=> String
  • 29. Open classes puts 123 #=> "123" class Fixnum def to_s "Not telling you!" end end puts 123 #=> "Not telling you!"
  • 30. Open classes puts 123 #=> "123" class Fixnum def to_s "Not telling you!" end end puts 123 #=> "Not telling you!" You probably don’t want to do this.
  • 31. Aliasing methods require "fileutils" class << FileUtils def rm_with_prompt *files print "Are you sure you want to delete #{files}? " response = gets.chomp.downcase return unless %w{yes y}.include?(response) rm_without_prompt *files end alias_method :rm_without_prompt, :rm alias_method :rm, :rm_with_prompt end FileUtils.rm "a_file"
  • 33. Blocks begin puts "This is a block, but it's not much use" end
  • 34. Blocks begin puts "This is a block, but it's not much use" end block = Proc.new do puts "Now I'm assigned to a variable" end # Nothing printed yet
  • 35. Blocks begin puts "This is a block, but it's not much use" end block = Proc.new do puts "Now I'm assigned to a variable" end # Nothing printed yet block.call #=> executes the block
  • 36. Blocks begin puts "This is a block, but it's not much use" end block = Proc.new do puts "Now I'm assigned to a variable" end # Nothing printed yet block.call #=> executes the block Proc.new { puts "curly brackets work too" }
  • 37. Blocks with arguments block = Proc.new do |arg| puts "You called me with #{arg.inspect}" end block.call("foo") #=> You called me with "foo"
  • 38. Explicit block args def n_times(n, &block) puts "starting..." n.times { block.call } puts "done." end n_times(3) do puts "hello" end #=> starting... #=> hello #=> hello #=> hello #=> done.
  • 39. Implicit block args def n_times(n) puts "starting..." n.times { yield } puts "done." end n_times(3) do puts "hello" end #=> starting... #=> hello #=> hello #=> hello #=> done.
  • 40. File IO with blocks
  • 41. File IO with blocks file = File.open "logfile", "a" file.puts "log message" file.close
  • 42. File IO with blocks file = File.open "logfile", "a" file.puts "log message" file.close File.open "logfile", "a" do |file| file.puts "log message" end
  • 44. Modules module InfoDisplay def display_info puts "Class: #{self.class}, ID: #{object_id}" end end class SomeClass include InfoDisplay end SomeClass.new.display_info #=> "Class: SomeClass, ID: 2159853660"
  • 45. Modules module InfoDisplay def display_info puts "Class: #{self.class}, ID: #{object_id}" end end class SomeClass include InfoDisplay end SomeClass.new.display_info #=> "Class: SomeClass, ID: 2159853660" String.send :include, InfoDisplay "foo".display_info #=> "Class: String, ID: 2159853520"
  • 46. Modules: Enumerable class Words include Enumerable def initialize string @words = string.split end def each @words.each {|word| yield word } end end words = Words.new("The quick brown fox") puts words.first #=> "The" puts words.count #=> 4 p words.select{|w| w.length == 3 } # => ["The", "fox"]
  • 48. Metaprogramming • Programs writing programs • Modify behaviour at runtime • Generate code • Respond dynamically to messages
  • 50. Evaluating code code = 'puts "hello"' eval code #=> "hello"
  • 51. Evaluating code code = 'puts "hello"' eval code #=> "hello" foo = "Ruby" foo.instance_eval do def hello puts "Hello, I'm #{self}" end end foo.hello #=> "Hello, I'm Ruby"
  • 53. Dynamic calling foo = "Hello" foo.upcase #=> "HELLO" foo.send :upcase #=> "HELLO"
  • 54. Dynamic calling foo = "Hello" foo.upcase #=> "HELLO" foo.send :upcase #=> "HELLO" method = [:upcase, :downcase][rand(2)] foo.send method #=> Randomly "HELLO" or "hello"
  • 55. Dynamic calling foo = "Hello" foo.upcase #=> "HELLO" foo.send :upcase #=> "HELLO" method = [:upcase, :downcase][rand(2)] foo.send method #=> Randomly "HELLO" or "hello" bar = 2 bar.send :+, 2 #=> 4
  • 56. Dynamic response class Foo def method_missing name, *args puts "You called #{name} with #{args.inspect}" end end Foo.new.bar(1, "hello") #=> You called bar with [1, "hello"]
  • 58. Rake require "erb" require "rake/clean" CLOBBER.include("output/*") OUTPUT_FILE = "output/README.txt" TEMPLATE_FILE = "templates/README.txt.erb" desc "Build the README file from the template" file OUTPUT_FILE => TEMPLATE_FILE do template = File.read(TEMPLATE_FILE) File.open(OUTPUT_FILE, "w") do |f| output = ERB.new(template).result(binding) f.write output end end task :default => [OUTPUT_FILE]
  • 59. Exercise 4 Rake
  • 60. Web frameworks and many more…
  • 61. Web servers Mongrel CGI Webrick
  • 68. A rack app require "rack" class HelloWorld def call env [200, {"Content-Type" => "text/plain"}, StringIO.new("Hello world")] end end run HelloWorld.new
  • 69. Exercise 5 Rack
  • 70. Shell scripting #!/usr/bin/env ruby require "fileutils" include FileUtils ARGV.each do |file| cp file, "#{file}.bak" end system "service httpd restart" #=> returns true or false users = `users`.split
  • 71. Testing • Test/Unit & SimpleTest • RSpec • Cucumber • Capybara
  • 72. JRuby • Another implementation of Ruby • Written in Java • Comparable or better performance • Use Java libraries from Ruby code • Deploy Rails apps as WAR files
  • 73. Calling Java from Ruby require 'java' frame = javax.swing.JFrame.new "Window" label = javax.swing.JLabel.new "Hello" frame.getContentPane.add label frame.setDefaultCloseOperation( javax.swing.JFrame::EXIT_ON_CLOSE) frame.pack frame.setVisible true
  • 74. Calling Ruby from Java import org.jruby.embed.ScriptingContainer; public class HelloWorld { private HelloWorld() { ScriptingContainer c = new ScriptingContainer(); c.runScriptlet("puts "Hello World!""); } public static void main(String[] args) { new HelloWorld(); } }
  • 75. while Time.now.hour < 17 audience_suggestions.pop.discuss end go :home

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n