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).

8c4cee1129bc11fbe9a0b9379dce2cb1?s=128

Rémi Prévost

February 23, 2012
Tweet

Transcript

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

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

  3. Objectif

  4. Vous convaincre d’essayer Ruby!

  5. Simple à apprendre

  6. Rapide à débuter

  7. Naturel à écrire

  8. Sondage rapide

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

  10. Ruby, le langage

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

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

    Ruby, le langage
  13. Minute historique

  14. None
  15. Installer Ruby

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

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

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

  19. Windows

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

  21. Hello World

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

    World.
  23. Types de données

  24. # Fixnum 7 # String "foo" # Array [4, 7,

    15, 16, 23, 42] # Hash { :foo => "bar", :omg => 3 }
  25. # Symbol :foo # Regex /[a-z]{0,10}\s+$/i # Proc lambda {

    |args| return "hello" } # NilClass nil
  26. Syntaxe pensée pour les développeurs

  27. puts "Hello world." # puts("Hello world.") puts :foo => :bar,

    :omg => 3 # puts({ :foo => :bar, :omg => 3 })
  28. nombres = ["un", "deux", "trois"] nombres.empty? => false nombres.first =>

    "un" nombres.include? "deux" => true
  29. puts "Hello" if total == 2 # ou if total

    == 2 puts "Hello" end
  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"
  31. [1, 2, 3].map { |x| x * 2 } #

    ou [1, 2, 3].map do |x| x * 2 end => [2, 4, 6]
  32. Modèle objet simple

  33. Tout est un objet

  34. Tout?

  35. Tout!

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

    FOO
  37. "foo".upcase => "FOO" 108.to_s => "108" [1, 2, 3, 4].shuffle

    => [2, 4, 1, 3] { :foo => "bar", :omg => 3 }.keys => [:foo, :omg]
  38. 10.times { |i| puts i } 0 1 2 3

    4 5 6 7 8 9
  39. 2 + 3 # ou # 2.+(3) => 5 [1,

    2, 3] << 4 # ou # [1, 2, 3].<<(4) => [1, 2, 3, 4]
  40. puts "Hello World." # Kernel.puts("Hello World.") require "../fichier.rb" # Kernel.require("../fichier.rb")

  41. Définir nos propres classes

  42. class Article end article = Article.new => #<Article:0x109bb6890>

  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
  44. Modèle objet souple

  45. Classes modifiables

  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!"
  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!"
  48. Classes internes modifiables (au runtime!)

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

    => "wbqbc"
  50. class Fixnum def minutes self * 60 end def hours

    self * 60.minutes end end 2.minutes => 120 5.hours => 18000
  51. class Object def lol! "LOL!" end end 1.lol! => "LOL!"

    "Test".lol! => "LOL!" [1, 2, 3].lol! => "LOL!"
  52. class NilClass def really? "Yep, really!" end end foo =

    nil foo.really? => "Yep, really!"
  53. Extension via modules

  54. module SuperModule def super! "Hé, #{self}, super!" end end class

    String include SuperModule end "Web à Québec".super! => "Hé, Web à Québec, super!"
  55. Librairies externes centralisées

  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
  57. Gems (moi je dis « une gem »)

  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
  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
  60. Ruby et le Web (à Québec)

  61. Historique Rack Frameworks • Rails • Sinatra Hébergement + déploiement

    Ruby et le Web
  62. Minute historique

  63. DHH

  64. Rack (une structure pour faire du Web)

  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
  66. Rack (une structure pour faire du Web)

  67. Interface serveur + code

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

    HTTP
  69. # Contenu de config.ru class Blogue def call(env) headers =

    { "Content-type" => "text/html" } [200, headers, "Hello world."] end end run Blogue.new
  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.
  71. Ruby on Rails

  72. “Full stack”

  73. ORM AJAX EMAIL TESTS MVC SESSIONS CSRF ROUTES DATABASE

  74. “Convention over configuration”

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

    HTTP Ruby
  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 .
  77. Ruby on Sinatra

  78. “Micro-framework”

  79. ORM AJAX EMAIL TESTS MVC SESSIONS CSRF ROUTES DATABASE

  80. “Add as you grow”

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

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

  83. Surprise, un blogue!

  84. $ tree . . !"" Gemfile !"" config.ru #"" blogue.rb

    0 directories, 3 files
  85. Configuration (avec Bundler)

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

    gem "dm-mysql-adapter" gem "dm-migrations" gem "haml"
  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"
  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!
  89. # Contenu de config.ru require "bundler" Bundler.require require "./blogue.rb" run

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

    port=9292
  91. Données (avec DataMapper)

  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!
  93. Article.all => [#<Article @id=1>, #<Article @id=2>, …] Article.all(:created_at.gte => Time.now

    - 3600) => [#<Article @id=3>] Article.get(42) => #<Article @id=42> Article.create(:title => "Hello!") => #<Article @id=1> Article.all(:title => "Un test").destroy => true
  94. Routes

  95. get "/" do … end post "/articles" do … end

    put "/articles/:id" do … end delete "/articles/:id" do … end
  96. get "/articles/:id" do # params[:id] end get /\/articles\/(?<id>[0-9]+)/ do #

    params[:id] end get "/articles/*" do # params[:splat] end get "/articles/:id.?:format?" do # params[:id], params[:format] end
  97. get "/" do @articles = Article.all end get "/articles/:id" do

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

  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" } }
  100. Vues (avec Haml)

  101. get "/" do @articles = Article.all end get "/articles/:id" do

    @article = Article.find(params[:id]) end
  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
  103. get "/" do @articles = Article.all haml :index end get

    "/articles/:id" do @article = Article.get(params[:id]) haml :show end
  104. Introduction à Haml

  105. %h1 Hello world. %p Voici une liste : %ul %li

    %a{ :href => "http://exomel.com" } Rémi <h1>Hello world.</h1> <p>Voici une liste :</p> <ul> <li> <a href="http://exomel.com">Rémi</a> </li> </ul>
  106. Fin de l’introduction à Haml

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

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

  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
  110. -# Contenu de views/blogue.haml !!! 5 %title Mon blogue %body

    = yield
  111. -# Exemple de http://localhost/articles/1 <!doctype html> <title>Mon blogue</title> <body> <h1>Lorem

    Ipsum</h1> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla dignissim, libero quis dapibus scelerisque
  112. Le code final

  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
  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
  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
  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
  117. Hébergement et déploiement

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

  119. Heroku (la magie)

  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
  121. mod_passenger (la transition idéale)

  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
  123. <VirtualHost *:80> ServerName blogue.webaquebec.org DocumentRoot /var/www/blogue/public <Directory /var/www/blogue/public> Allow from

    all Options -MultiViews </Directory> </VirtualHost> $ cd /var/www/blogue $ mkdir public $ mkdir tmp $ sudo apachectl restart
  124. $ touch tmp/restart.txt

  125. Résumé (en 30 secondes)

  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
  127. Ressources utiles

  128. Ressources utiles

  129. Ressources utiles • sinatrarb.com • guides.rubyonrails.org • haml-lang.com • github.com/explore/languages/ruby

    • heroku.com • modrails.com (Apache et nginx)
  130. Merci! Rémi Prévost — http://exomel.com @remi