Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction à Ruby

Introduction à Ruby

Présentation donnée le 23 février 2012 au Web à Québec 2012 (Québec).

Rémi Prévost

February 23, 2012
Tweet

More Decks by Rémi Prévost

Other Decks in Technology

Transcript

  1. Introduction à
    Ruby
    Rémi Prévost — Web à Québec 2012

    View Slide

  2. Rémi Prévost
    Développeur Web qui aime Ruby
    freelance!

    View Slide

  3. Objectif

    View Slide

  4. Vous convaincre
    d’essayer Ruby!

    View Slide

  5. Simple
    à apprendre

    View Slide

  6. Rapide
    à débuter

    View Slide

  7. Naturel
    à écrire

    View Slide

  8. Sondage
    rapide

    View Slide

  9. Ruby, le langage
    Ruby et le Web
    Introduction à Ruby

    View Slide

  10. Ruby,
    le langage

    View Slide

  11. “I’ve made a
    huge mistake.”

    View Slide

  12. Historique
    Installation
    Types de données
    Syntaxe particulière
    Modèle objet
    Gems
    Ruby, le langage

    View Slide

  13. Minute
    historique

    View Slide

  14. View Slide

  15. Installer
    Ruby

    View Slide

  16. $ ruby -v
    ruby 1.8.7 (2010-01-10 patchlevel 249)
    Mac OS X

    View Slide

  17. $ brew install rbenv ruby-build
    $ rbenv install 1.9.2-p290
    Mac OS X

    View Slide

  18. $ sudo apt-get install ruby-1.9.1-full
    Ubuntu/Debian

    View Slide

  19. Windows

    View Slide

  20. $ irb
    ruby-1.9.2-p290 :001 >

    View Slide

  21. Hello
    World

    View Slide

  22. # Contenu de hello.rb
    puts("Hello World.")
    $ ruby hello.rb
    Hello World.

    View Slide

  23. Types de
    données

    View Slide

  24. # Fixnum
    7
    # String
    "foo"
    # Array
    [4, 7, 15, 16, 23, 42]
    # Hash
    { :foo => "bar", :omg => 3 }

    View Slide

  25. # Symbol
    :foo
    # Regex
    /[a-z]{0,10}\s+$/i
    # Proc
    lambda { |args| return "hello" }
    # NilClass
    nil

    View Slide

  26. Syntaxe pensée pour les
    développeurs

    View Slide

  27. puts "Hello world."
    # puts("Hello world.")
    puts :foo => :bar, :omg => 3
    # puts({ :foo => :bar, :omg => 3 })

    View Slide

  28. nombres = ["un", "deux", "trois"]
    nombres.empty?
    => false
    nombres.first
    => "un"
    nombres.include? "deux"
    => true

    View Slide

  29. puts "Hello" if total == 2
    # ou
    if total == 2
    puts "Hello"
    end

    View Slide

  30. def hello(name)
    another_method("foo")
    return "Hello, #{name.capitalize}"
    end
    # ou
    def hello(name)
    another_method("foo")
    "Hello, #{name.capitalize}"
    end
    hello("rémi")
    => "Hello, Rémi"

    View Slide

  31. [1, 2, 3].map { |x| x * 2 }
    # ou
    [1, 2, 3].map do |x|
    x * 2
    end
    => [2, 4, 6]

    View Slide

  32. Modèle objet
    simple

    View Slide

  33. Tout est un
    objet

    View Slide

  34. Tout?

    View Slide

  35. Tout!

    View Slide

  36. upcase("foo")
    => NoMethodError: undefined method
    `upcase' for main:Object
    "foo".upcase
    => FOO

    View Slide

  37. "foo".upcase
    => "FOO"
    108.to_s
    => "108"
    [1, 2, 3, 4].shuffle
    => [2, 4, 1, 3]
    { :foo => "bar", :omg => 3 }.keys
    => [:foo, :omg]

    View Slide

  38. 10.times { |i| puts i }
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

    View Slide

  39. 2 + 3
    # ou
    # 2.+(3)
    => 5
    [1, 2, 3] << 4
    # ou
    # [1, 2, 3].<=> [1, 2, 3, 4]

    View Slide

  40. puts "Hello World."
    # Kernel.puts("Hello World.")
    require "../fichier.rb"
    # Kernel.require("../fichier.rb")

    View Slide

  41. Définir nos propres
    classes

    View Slide

  42. class Article
    end
    article = Article.new
    => #

    View Slide

  43. class Article < Contenu
    attr_reader :published
    def initialize(published=true)
    @published = published
    end
    def publish!
    @published = true
    end
    end
    article = Article.new(false)
    article.publish!
    article.published
    => true

    View Slide

  44. Modèle objet
    souple

    View Slide

  45. Classes
    modifiables

    View Slide

  46. class Article
    def delete
    puts "Suppression de l’article!"
    end
    end
    class Article
    def delete
    puts "Finalement, on ne fait rien!"
    end
    end
    article = Article.new
    article.delete
    => "Finalement, on ne fait rien!"

    View Slide

  47. class Article
    def delete
    puts "Suppression de l’article!"
    end
    end
    article = Article.new
    class Article
    def delete
    puts "Finalement, on ne fait rien!"
    end
    end
    article.delete
    => "Finalement, on ne fait rien!"

    View Slide

  48. Classes internes
    modifiables
    (au runtime!)

    View Slide

  49. class String
    def sans_les_voyelles
    self.gsub /[aeiouy]/i, ""
    end
    end
    "webaquebec".sans_les_voyelles
    => "wbqbc"

    View Slide

  50. class Fixnum
    def minutes
    self * 60
    end
    def hours
    self * 60.minutes
    end
    end
    2.minutes
    => 120
    5.hours
    => 18000

    View Slide

  51. class Object
    def lol!
    "LOL!"
    end
    end
    1.lol!
    => "LOL!"
    "Test".lol!
    => "LOL!"
    [1, 2, 3].lol!
    => "LOL!"

    View Slide

  52. class NilClass
    def really?
    "Yep, really!"
    end
    end
    foo = nil
    foo.really?
    => "Yep, really!"

    View Slide

  53. Extension via
    modules

    View Slide

  54. module SuperModule
    def super!
    "Hé, #{self}, super!"
    end
    end
    class String
    include SuperModule
    end
    "Web à Québec".super!
    => "Hé, Web à Québec, super!"

    View Slide

  55. Librairies externes
    centralisées

    View Slide

  56. $ ls /var/www/mon-application-php
    wp-atom.php wp-feed.php index.php
    wp-blog-header.php wp-includes/ license.txt
    wp-comments-post.php wp-opml.php wp-login.php
    wp-commentsrss2.php wp-load.php wp-pass.php
    readme.html wp-config.php wp-rdf.php
    wp-activate.php wp-mail.php
    wp-admin/ wp-content/
    wp-app.php wp-cron.php
    $ ls /var/www/mon-application-ruby
    Gemfile Gemfile.lock config.ru app.rb

    View Slide

  57. Gems
    (moi je dis « une gem »)

    View Slide

  58. $ gem install httparty
    Fetching: multi_xml-0.4.1.gem (100%)
    Fetching: httparty-0.8.1.gem (100%)
    When you HTTParty, you must party hard!
    Successfully installed multi_xml-0.4.1
    Successfully installed httparty-0.8.1
    2 gems installed
    $ irb
    >> HTTParty
    NameError: uninitialized constant Object::HTTParty
    >> require "httparty"
    => true
    >> HTTParty
    => HTTParty

    View Slide

  59. $ bundle --version
    command not found: bundle
    $ gem install bundler
    Successfully installed bundler-1.0.22
    1 gem installed
    $ bundle --version
    Bundler version 1.0.22

    View Slide

  60. Ruby et le
    Web
    (à Québec)

    View Slide

  61. Historique
    Rack
    Frameworks
    • Rails
    • Sinatra
    Hébergement + déploiement
    Ruby et le Web

    View Slide

  62. Minute
    historique

    View Slide

  63. DHH

    View Slide

  64. Rack
    (une structure pour faire du Web)

    View Slide

  65. $ tree .
    .
    !"" a-propos.rb
    !"" index.rb
    #"" projets.rb
    0 directories, 3 files
    $ curl http://localhost/index.rb
    Ma page d’accueil!
    $ curl http://localhost/a-propos.rb
    Moi, bla bla bla.
    NOPE

    View Slide

  66. Rack
    (une structure pour faire du Web)

    View Slide

  67. Interface
    serveur +
    code

    View Slide

  68. Utilisateur
    Serveur Web
    Rack
    Ruby
    Rack
    Serveur Web
    Utilisateur
    Requête HTTP

    View Slide

  69. # Contenu de config.ru
    class Blogue
    def call(env)
    headers = { "Content-type" => "text/html" }
    [200, headers, "Hello world."]
    end
    end
    run Blogue.new

    View Slide

  70. $ gem install rack
    $ rackup config.ru
    WEBrick 1.3.1
    ruby 1.9.2 (2011-07-09)
    WEBrick::HTTPServer#start: pid=69232 port=9292
    $ curl http://localhost:9292
    Hello world.
    $ curl http://localhost:9292/foo/bar
    Hello world.

    View Slide

  71. Ruby on
    Rails

    View Slide

  72. “Full stack”

    View Slide

  73. ORM
    AJAX
    EMAIL
    TESTS
    MVC
    SESSIONS
    CSRF
    ROUTES
    DATABASE

    View Slide

  74. “Convention
    over
    configuration”

    View Slide

  75. Utilisateur
    Serveur Web
    Rack
    Rails
    Rack
    Serveur Web
    Utilisateur
    Requête HTTP
    Ruby

    View Slide

  76. $ rails new mon_application

    $ du --max-depth 1 -h .
    28K ./app
    60K ./config
    4,0K ./db
    4,0K ./doc
    0 ./lib
    0 ./log
    24K ./public
    4,0K ./script
    8,0K ./test
    0 ./tmp
    0 ./vendor
    164K .

    View Slide

  77. Ruby on
    Sinatra

    View Slide

  78. “Micro-framework”

    View Slide

  79. ORM
    AJAX
    EMAIL
    TESTS
    MVC
    SESSIONS
    CSRF
    ROUTES
    DATABASE

    View Slide

  80. “Add as you grow”

    View Slide

  81. Utilisateur
    Serveur Web
    Rack
    Sinatra
    Rack
    Serveur Web
    Utilisateur
    Requête HTTP
    Ruby

    View Slide

  82. Configuration (Bundler)
    Données (DataMapper)
    Routes
    Vues (Haml)
    Sinatra

    View Slide

  83. Surprise,
    un blogue!

    View Slide

  84. $ tree .
    .
    !"" Gemfile
    !"" config.ru
    #"" blogue.rb
    0 directories, 3 files

    View Slide

  85. Configuration
    (avec Bundler)

    View Slide

  86. # Contenu de Gemfile
    source "http://rubygems.org"
    gem "sinatra"
    gem "dm-core"
    gem "dm-mysql-adapter"
    gem "dm-migrations"
    gem "haml"

    View Slide

  87. # Contenu de Gemfile
    source "http://rubygems.org"
    gem "sinatra", "~> 1.3"
    gem "dm-core"
    gem "dm-mysql-adapter"
    gem "dm-migrations"
    gem "haml", "3.1"

    View Slide

  88. $ bundle install
    => Fetching gem metadata from http://rubygems.org/
    Installing addressable (…)
    Installing data_objects (…)
    Installing dm-core (…)
    Installing dm-mysql-adapter (…)
    Installing dm-migrations (…)
    Installing rack (…)
    Installing tilt (…)
    Installing sinatra (…)
    Installing haml (…)
    Using bundler (…)
    Your bundle is complete!

    View Slide

  89. # Contenu de config.ru
    require "bundler"
    Bundler.require
    require "./blogue.rb"
    run Sinatra::Application

    View Slide

  90. $ rackup config.ru
    WEBrick 1.3.1
    ruby 1.9.2 (2011-07-09)
    WEBrick::HTTPServer#start: pid=69232 port=9292

    View Slide

  91. Données
    (avec DataMapper)

    View Slide

  92. # Contenu de blogue.rb
    configure do
    DataMapper::Logger.new(STDOUT, :debug)
    DataMapper.setup(:default, "mysql://localhost/blogue")
    end
    class Article
    include DataMapper::Resource # Un module!
    property :id, Serial
    property :title, String
    property :content, Text
    property :created_at, DateTime
    end
    DataMapper.finalize
    DataMapper.auto_upgrade!

    View Slide

  93. Article.all
    => [#, #, …]
    Article.all(:created_at.gte => Time.now - 3600)
    => [#]
    Article.get(42)
    => #
    Article.create(:title => "Hello!")
    => #
    Article.all(:title => "Un test").destroy
    => true

    View Slide

  94. Routes

    View Slide

  95. get "/" do

    end
    post "/articles" do

    end
    put "/articles/:id" do

    end
    delete "/articles/:id" do

    end

    View Slide

  96. get "/articles/:id" do
    # params[:id]
    end
    get /\/articles\/(?[0-9]+)/ do
    # params[:id]
    end
    get "/articles/*" do
    # params[:splat]
    end
    get "/articles/:id.?:format?" do
    # params[:id], params[:format]
    end

    View Slide

  97. get "/" do
    @articles = Article.all
    end
    get "/articles/:id" do
    @article = Article.get(params[:id])
    end

    View Slide

  98. post "/articles" do
    @article = Article.create(params[:article])
    redirect to("/articles/#{@article.id}")
    end

    View Slide

  99. $ curl http://localhost:9292/articles
    -X POST
    --data "article[title]=Mon+article"
    --data "article[content]=Le+contenu"
    params
    => {
    :article => {
    :title => "Mon article",
    :content => "Mon contenu"
    }
    }

    View Slide

  100. Vues
    (avec Haml)

    View Slide

  101. get "/" do
    @articles = Article.all
    end
    get "/articles/:id" do
    @article = Article.find(params[:id])
    end

    View Slide

  102. get "/" do
    @articles = Article.all
    "Il y a #{@articles.length} articles."
    end
    get "/articles/:id" do
    @article = Article.get(params[:id])
    "C’est bien #{@article.title}."
    end

    View Slide

  103. get "/" do
    @articles = Article.all
    haml :index
    end
    get "/articles/:id" do
    @article = Article.get(params[:id])
    haml :show
    end

    View Slide

  104. Introduction à
    Haml

    View Slide

  105. %h1 Hello world.
    %p Voici une liste :
    %ul
    %li
    %a{ :href => "http://exomel.com" } Rémi
    Hello world.
    Voici une liste :


    Rémi


    View Slide

  106. Fin de
    l’introduction à
    Haml

    View Slide

  107. -# Contenu de views/index.haml
    %ul
    - @articles.each do |article|
    %li
    %h1= article.title
    = article.content

    View Slide

  108. -# Contenu de views/show.haml
    %h1= @article.title
    = @article.content

    View Slide

  109. get "/" do
    @articles = Article.all
    haml :index, :layout => :blogue
    end
    get "/articles/:id" do
    @article = Article.get(params[:id])
    haml :show, :layout => :blogue
    end

    View Slide

  110. -# Contenu de views/blogue.haml
    !!! 5
    %title Mon blogue
    %body
    = yield

    View Slide

  111. -# Exemple de http://localhost/articles/1

    Mon blogue

    Lorem Ipsum
    Lorem ipsum dolor sit amet, consectetur
    adipiscing elit. Nulla dignissim, libero quis
    dapibus scelerisque

    View Slide

  112. Le code final

    View Slide

  113. # Contenu de blogue.rb
    configure do
    DataMapper::Logger.new STDOUT, :debug
    DataMapper.setup :default, "mysql://localhost/blogue"
    class Article
    include DataMapper::Resource
    property :id, Serial
    property :title, String
    property :content, Text
    property :created_at, DateTime
    end
    DataMapper.finalize
    DataMapper.auto_upgrade!
    end

    View Slide

  114. # Suite de blogue.rb
    get "/" do
    @articles = Article.all
    haml :index, :layout => :blogue
    end
    get "/articles/:id" do
    @article = Article.get(params[:id])
    haml :show, :layout => :blogue
    end
    post "/articles" do
    @article = Article.create(params[:article])
    redirect to("/article/#{@article.id}")
    end

    View Slide

  115. -# Contenu de views/index.haml
    %ul
    - @articles.each do |article|
    %li
    %h1= article.title
    = article.content
    -# Contenu de views/show.haml
    %h1= @article.title
    = @article.content
    -# Contenu de views/blogue.haml
    !!! 5
    %title Mon blogue
    %body
    = yield

    View Slide

  116. configure do
    DataMapper::Logger.new STDOUT, :debug
    DataMapper.setup :default, "mysql://localhost/blogue"
    class Article
    include DataMapper::Resource
    property :id, Serial
    property :title, String
    property :content, Text
    property :created_at, DateTime
    end
    DataMapper.finalize
    DataMapper.auto_upgrade!
    end
    get "/" do
    @articles = Article.all
    haml :index, :layout => :blogue
    end
    get "/articles/:id" do
    @article = Article.find(params[:id])
    haml :show, :layout => :blogue
    end
    post "/articles" do
    @article = Article.create(params[:article])
    redirect to("/article/#{@article.id}")
    end

    View Slide

  117. Hébergement
    et déploiement

    View Slide

  118. Le mythe
    (« omg, ruby c’est compliqué! »)

    View Slide

  119. Heroku
    (la magie)

    View Slide

  120. $ gem install heroku
    $ heroku apps:create blogue
    Creating blogue... done
    Git remote heroku added
    $ git push heroku master
    -----> Heroku receiving push
    -----> Ruby/Rack app detected
    -----> Gemfile detected, running Bundler version 1.0.7
    Unresolved dependencies detected; Installing...
    Your bundle is complete!
    -----> Launching... done, v1
    http://blogue.heroku.com deployed to Heroku

    View Slide

  121. mod_passenger
    (la transition idéale)

    View Slide

  122. $ sudo gem install passenger
    $ sudo passenger-install-apache2-module
    LoadModule passenger_module /usr/lib/ruby/gems/
    1.9.1/gems/passenger-3.0.11/ext/apache2/
    mod_passenger.so
    PassengerRoot /usr/lib/ruby/gems/1.9.1/gems/
    passenger-3.0.11
    PassengerRuby /usr/bin/ruby1.9.1

    View Slide


  123. ServerName blogue.webaquebec.org
    DocumentRoot /var/www/blogue/public

    Allow from all
    Options -MultiViews


    $ cd /var/www/blogue
    $ mkdir public
    $ mkdir tmp
    $ sudo apachectl restart

    View Slide

  124. $ touch tmp/restart.txt

    View Slide

  125. Résumé
    (en 30 secondes)

    View Slide

  126. $ sudo gem install sinatra
    $ cat config.ru
    require "sinatra"
    get "/" do
    "Hello world."
    end
    run Sinatra::Application
    $ rackup config.ru
    WEBrick 1.3.1
    ruby 1.9.2 (2011-07-09)
    WEBrick::HTTPServer#start: pid=69232 port=9292

    View Slide

  127. Ressources
    utiles

    View Slide

  128. Ressources utiles

    View Slide

  129. Ressources utiles
    • sinatrarb.com
    • guides.rubyonrails.org
    • haml-lang.com
    • github.com/explore/languages/ruby
    • heroku.com
    • modrails.com (Apache et nginx)

    View Slide

  130. Merci!
    Rémi Prévost — http://exomel.com
    @remi

    View Slide