intro to ruby
                              brian hogan
               New Auburn Personal Computer Services LLC




twitter: bphogan
email: brianhogan at napcs.com
programming is fun.


twitter: bphogan
email: brianhogan at napcs.com
you just don’t know it
                     yet.

twitter: bphogan
email: brianhogan at napcs.com
I was a designer. I hated
              programming.

twitter: bphogan
email: brianhogan at napcs.com
my clients wanted
             interactive websites...

twitter: bphogan
email: brianhogan at napcs.com
and I started to hate
                     my life.


twitter: bphogan
email: brianhogan at napcs.com
I learned Ruby in 2005
               and fell in love...

twitter: bphogan
email: brianhogan at napcs.com
twitter: bphogan
email: brianhogan at napcs.com
So what can kinds of
           things can you do with
                    Ruby?

twitter: bphogan
email: brianhogan at napcs.com
Shoes.app do
    para "Item name"
    @name = edit_line

    button "Add to list" do
     @names.append do
      para @name.text
     end
     @name.text = ""
    end

    button("Clear the list") {@names.clear}

    @names = stack :width=>"100%", :height=>"90%"

   end




twitter: bphogan
email: brianhogan at napcs.com
require 'sinatra'
require 'pathname'

get "/" do
 dir = "./files/"
 @links = Dir[dir+"*"].map { |file|
   file_link(file)
 }.join
 erb :index
end

helpers do

 def file_link(file)
  filename = Pathname.new(file).basename
  "<li><a href='#{file}' target='_self'>#{filename}</a></li>"
 end

end

use_in_file_templates!

__END__

@@ index
<html>
 <head>
  <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
  <style type="text/css" media="screen">@import "/stylesheets/iui.css";</style>
  <script type="application/x-javascript" src="/javascripts/iui.js"></script>
 </head>

 <body>
  <div class="toolbar">
  <h1 id="pageTitle"></h1>
  </div>
  <ul id="home" title="Your files, sir." selected="true">
    <%= @links %>
  </ul>
 </body>

</html>


twitter: bphogan
email: brianhogan at napcs.com
!the_border = 1px
     !base_color = #111
                                        #header {
     #header                              color: #333333;
       color = !base_color * 3            border-left: 1px;
       border-left= !the_border           border-right: 2px;
       border-right = !the_border * 2     color: red; }
       color: red                         #header a {
                                            font-weight: bold;
       a                                    text-decoration: none; }
           font-weight: bold
           text-decoration: none




twitter: bphogan
email: brianhogan at napcs.com
got a great idea and
         want to get it out there
                quickly?

twitter: bphogan
email: brianhogan at napcs.com
twitter: bphogan
email: brianhogan at napcs.com
got a big site that’s hard
               to maintain?

twitter: bphogan
email: brianhogan at napcs.com
twitter: bphogan
email: brianhogan at napcs.com
So, what is Ruby?
• Highly dynamic
• Very high level
• 100% object oriented
• 100% open-source
• Really easy to learn
History

    Smalltalk          C++         Ruby     Java     VB 6      C#
     (1983)           (1989)      (1993)   (1995)   (1996)   (2000)




twitter: bphogan
email: brianhogan at napcs.com
twitter: bphogan
email: brianhogan at napcs.com
Ruby follows the
                    Principle of Least
                        Surprise.

twitter: bphogan
email: brianhogan at napcs.com
consistent API
"Brian".length
["red", "green", "blue"].length
[:first_name => "Brian", :last_name => "Hogan"].length
User.find_all_by_last_name("Hogan").length
and a simple syntax
age = 42
first_name = "Homer"
start_date = Date.new 1980, 06, 05
annual_salary = 100000.00
Basic Ruby


twitter: bphogan
email: brianhogan at napcs.com
Standard operators


 5 + 5
 10 * 10
 "Hello" + "World"
 25 / 5
Arrays


colors = ["Red", "Green", "Blue"]
Hashes (Dictionaries)


attributes = {:age => 25,
              :first_name => "Homer",
              :last_name => "Simpson"}
=>
:foo


twitter: bphogan
email: brianhogan at napcs.com
Simple control logic
if on_probation(start_date)
  puts "Yes"
else
  puts "no"
end
Unless
if !current_user.admin?
  redirect_to "/login"
end




unless current_user.admin?
  redirect_to "/login"
end
Conditionals as statement suffixes

redirect_to "/login" unless current_user.admin?
Methods (functions) are simple too.


 # if start date + 6 months is > today
 def on_probation?(start_date)
   (start_date >> 6) > Date.today
 end
Classes are easy too.
class Person
  @started_on = Date.today
  @name = ""

  def started_on=(date)
    @started_on = date
  end

  def started_on
    @started_on
  end

end
Class instance variables are private
class Person
  @started_on = Date.today
                               Expose them through
  @name = ""
                               accessor methods that
  def started_on=(date)
    @started_on = date          resemble C# and VB
  end
                                 Property members.
  def started_on
    @started_on
  end                            person = Person.new
                                 person.age = 32
  def name=(name)                person.name = "Brian"
    @name = name
  end
                                 person.age
                                 => 32
  def name                       person.name
    @name
                                 => "Brian"
  end
end
Let Ruby write code for you!
class Person
  @started_on = Date.today
  @name = ""

  def started_on=(date)
                                  class Person
    @started_on = date
  end                               attr_accessor :name
                                    attr_accessor :started_on
  def started_on
    @started_on                   end
  end

  def name=(name)
    @name = name
  end

  def name
    @name
  end
end
Ruby is a loaded gun.


twitter: bphogan
email: brianhogan at napcs.com
So, write good tests.


twitter: bphogan
email: brianhogan at napcs.com
TATFT


twitter: bphogan
email: brianhogan at napcs.com
def test_user_hired_today_should_be_on_probation
  person = Person.new
  person.hired_on = Date.today
  assert person.on_probation?
end


test_user_hired_last_year_should_not_be_on_probation
  person = Person.new
  person.hired_on = 1.year.ago
  assert !person.on_probation?
end
Implement the method
class Person
  attr_accessor :name, :start_date

  def on_probation?
    (start_date >> 6) > Date.today
  end
end
And the tests pass.


twitter: bphogan
email: brianhogan at napcs.com
Testing first helps you
         think about your design
           AND your features.

twitter: bphogan
email: brianhogan at napcs.com
Every professional Ruby
         developer writes tests
          first for production
                 code.
twitter: bphogan
email: brianhogan at napcs.com
Ten Simple Rules
 For Programming in
My Favorite Language.
1. Everything is an
                         object


twitter: bphogan
email: brianhogan at napcs.com
25.class     Fixnum



"brian".class   String



[1,2,3].class   Array
2. Everything evaluates
            to true except nil or
                    false

twitter: bphogan
email: brianhogan at napcs.com
x = 0
              0
puts x if x



x = -1
              -1
puts x if x



x = false
              nil
puts x if x



x = nil
              nil
puts x if x
3. Variables are
          dynamically typed but
         DATA is strongly typed!

twitter: bphogan
email: brianhogan at napcs.com
age = 32
name = "Brian"    TypeError: can't convert Fixnum into String
name + age




age = 32
name = "Brian"                    “Brian32”
name + age.to_s
4. Every method
                  returns the last
                evaluation implicitly

twitter: bphogan
email: brianhogan at napcs.com
def limit_reached?
  self.projects.length > 0
end


def welcome_message
  if current_user.anonymous?
    "You need to log in."
  else
    "Welcome!"
  end
end
5. Every expression
            evaluates to an object


twitter: bphogan
email: brianhogan at napcs.com
result = if current_user.anonymous?
           "You need to log in."
         else
           "Welcome!"
         end
It is very easy to accidentally return false!
       def before_save
         if self.status == "closed"
           self.closed_on = Date.today
         end
       end
6. Classes are objects


twitter: bphogan
email: brianhogan at napcs.com
WRONG!
person = new Person




    RIGHT!
person = Person.new
7. You need to use and
             understand blocks.

twitter: bphogan
email: brianhogan at napcs.com
Blocks can iterate


roles.each do |role|
  puts "<li>" + role.name + "<li>"
end
They can also encapsulate code.



  ActiveRecord::Schema.define do
    create_table :pages do |t|
      t.string :name
      t.text :body
      t.timestamps
    end
  end
Every method can take a block!




      5.times do
        puts "Hello!"
      end
8. Favor modules over
                  inheritance


twitter: bphogan
email: brianhogan at napcs.com
module SharedValidations
         def self.included(base)
           base.validates_presence_of :name
           base.validates_uniqueness_of :name
         end
       end




class Project                 class Task
  include SharedValidations     include SharedValidations
end                           end
Do not use type,
                     use behaviors.


twitter: bphogan
email: brianhogan at napcs.com
twitter: bphogan
email: brianhogan at napcs.com
module Doctor            module Ninja
  def treat_patient        def attack
    puts "All better!"       puts "You’re dead!"
  end                      end
end                      end


module Musician
  def play_guitar
    puts "meedily-meedily-meedily-meeeeeeeeee!"
  end
end
person = Person.new
person.extend Ninja      "You're dead!"
person.attack


person.extend Doctor
                         "All better!"
person.treat_patient



person.extend Musician   "meedily-meedily-
person.play_guitar       meedily-meeeeeeeeee!"
9. Embrace Reflection


twitter: bphogan
email: brianhogan at napcs.com
person.respond_to?(:name)   true




person.respond_to?(:age)    false




person.send(:name)          “Brian”
10. Write code that
                    writes code.

twitter: bphogan
email: brianhogan at napcs.com
class User
  ROLES = ["admin", "superadmin", "user", "moderator"]
  ROLES.each do |role|
    class_eval <<-EOF
      def #{role}?
        self.roles.include?("#{role}")
      end
    EOF
  end
end




                user = User.new
                user.admin?
                user.moderator?
haml and sass


twitter: bphogan
email: brianhogan at napcs.com
HAML
!!!
#wrapper.container_12
  #header.grid_12
    %h1 The awesome site
  %ul#navbar.grid_12
    %li
      %a{:href => "index.html"} Home
    %li
      %a{:href => "products"} Products
    %li
      %a{:href => "services"} Services
  #middle.grid_12
    %h2 Welcome

 #footer.grid_12
   %p Copyright 2009 SomeCompany
HTML
<div class='container_12' id='wrapper'>
   <div class='grid_12' id='header'>
     <h1>The awesome site</h1>
   </div>
   <ul class='grid_12' id='navbar'>
     <li>
        <a href='index.html'>Home</a>
     </li>
     <li>
        <a href='products'>Products</a>
     </li>
     <li>
        <a href='services'>Services</a>
     </li>
   </ul>
   <div class='grid_12' id='middle'>
     <h2>Welcome</h2>
   </div>
   <div class='grid_12' id='footer'>
     <p>Copyright 2009 SomeCompany</p>
   </div>
 </div>
SASS

!the_border = 1px
!base_color = #111

#header
  color = !base_color * 3
  border-left= !the_border
  border-right = !the_border * 2
  color: red

 a
     font-weight: bold
     text-decoration: none
CSS

#header {
  color: #333333;
  border-left: 1px;
  border-right: 2px;
  color: red; }

 #header a {
   font-weight: bold;
   text-decoration: none; }
StaticMatic demo


twitter: bphogan
email: brianhogan at napcs.com
sinatra


twitter: bphogan
email: brianhogan at napcs.com
Hello Sinatra!


require 'rubygems'
require 'sinatra'

get "/" do
  "Hello Sinatra!"
end
Sinatra demo


twitter: bphogan
email: brianhogan at napcs.com
cucumber


twitter: bphogan
email: brianhogan at napcs.com
Feature: creating a new page in the wiki
As an average anonymous user
I want to create a page about Ruby
So that I can tell everyone how awesome it is.

Scenario: Creating a new page and editing its content
Given I go to "/ruby"
 Then I should see "Edit this page"
 When I click "Edit this page"
 And I fill in "body" with "Ruby is the best programming language in the whole world!"
 And I press "Save"
 Then I should see "Ruby is the best programming language in the whole world!"




twitter: bphogan
email: brianhogan at napcs.com
Testing the Wiki with
          Webrat and Cucumber


twitter: bphogan
email: brianhogan at napcs.com
Ruby will make you
                   productive.


twitter: bphogan
email: brianhogan at napcs.com
And happy.


twitter: bphogan
email: brianhogan at napcs.com
Resources:
 Try Ruby in your browser! http://tryruby.sophrinix.com/
         Try SASS online: http://sass-lang.com/try.html
        Try HAML online: http://haml-lang.com/try.html
                http://staticmatic.rubyforge.org/
              Sinatra: http://www.sinatrarb.com/
     Sinatra Wiki source: http://github.com/napcs/sinatriki
                  Cucumber: http://cukes.info/
                   WATIR: http://watir.com/

twitter: bphogan
email: brianhogan at napcs.com
Questions?
             Twitter: bphogan
         brianhogan at napcs.com

twitter: bphogan
email: brianhogan at napcs.com

Intro to Ruby

  • 1.
    intro to ruby brian hogan New Auburn Personal Computer Services LLC twitter: bphogan email: brianhogan at napcs.com
  • 2.
    programming is fun. twitter:bphogan email: brianhogan at napcs.com
  • 3.
    you just don’tknow it yet. twitter: bphogan email: brianhogan at napcs.com
  • 4.
    I was adesigner. I hated programming. twitter: bphogan email: brianhogan at napcs.com
  • 5.
    my clients wanted interactive websites... twitter: bphogan email: brianhogan at napcs.com
  • 6.
    and I startedto hate my life. twitter: bphogan email: brianhogan at napcs.com
  • 7.
    I learned Rubyin 2005 and fell in love... twitter: bphogan email: brianhogan at napcs.com
  • 8.
  • 9.
    So what cankinds of things can you do with Ruby? twitter: bphogan email: brianhogan at napcs.com
  • 10.
    Shoes.app do para "Item name" @name = edit_line button "Add to list" do @names.append do para @name.text end @name.text = "" end button("Clear the list") {@names.clear} @names = stack :width=>"100%", :height=>"90%" end twitter: bphogan email: brianhogan at napcs.com
  • 11.
    require 'sinatra' require 'pathname' get"/" do dir = "./files/" @links = Dir[dir+"*"].map { |file| file_link(file) }.join erb :index end helpers do def file_link(file) filename = Pathname.new(file).basename "<li><a href='#{file}' target='_self'>#{filename}</a></li>" end end use_in_file_templates! __END__ @@ index <html> <head> <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/> <style type="text/css" media="screen">@import "/stylesheets/iui.css";</style> <script type="application/x-javascript" src="/javascripts/iui.js"></script> </head> <body> <div class="toolbar"> <h1 id="pageTitle"></h1> </div> <ul id="home" title="Your files, sir." selected="true"> <%= @links %> </ul> </body> </html> twitter: bphogan email: brianhogan at napcs.com
  • 12.
    !the_border = 1px !base_color = #111 #header { #header color: #333333; color = !base_color * 3 border-left: 1px; border-left= !the_border border-right: 2px; border-right = !the_border * 2 color: red; } color: red #header a { font-weight: bold; a text-decoration: none; } font-weight: bold text-decoration: none twitter: bphogan email: brianhogan at napcs.com
  • 13.
    got a greatidea and want to get it out there quickly? twitter: bphogan email: brianhogan at napcs.com
  • 14.
  • 15.
    got a bigsite that’s hard to maintain? twitter: bphogan email: brianhogan at napcs.com
  • 16.
  • 17.
    So, what isRuby? • Highly dynamic • Very high level • 100% object oriented • 100% open-source • Really easy to learn
  • 18.
    History Smalltalk C++ Ruby Java VB 6 C# (1983) (1989) (1993) (1995) (1996) (2000) twitter: bphogan email: brianhogan at napcs.com
  • 19.
  • 20.
    Ruby follows the Principle of Least Surprise. twitter: bphogan email: brianhogan at napcs.com
  • 21.
    consistent API "Brian".length ["red", "green","blue"].length [:first_name => "Brian", :last_name => "Hogan"].length User.find_all_by_last_name("Hogan").length
  • 22.
    and a simplesyntax age = 42 first_name = "Homer" start_date = Date.new 1980, 06, 05 annual_salary = 100000.00
  • 23.
    Basic Ruby twitter: bphogan email:brianhogan at napcs.com
  • 24.
    Standard operators 5+ 5 10 * 10 "Hello" + "World" 25 / 5
  • 25.
    Arrays colors = ["Red","Green", "Blue"]
  • 26.
    Hashes (Dictionaries) attributes ={:age => 25, :first_name => "Homer", :last_name => "Simpson"}
  • 27.
  • 28.
  • 29.
    Simple control logic ifon_probation(start_date) puts "Yes" else puts "no" end
  • 30.
    Unless if !current_user.admin? redirect_to "/login" end unless current_user.admin? redirect_to "/login" end
  • 31.
    Conditionals as statementsuffixes redirect_to "/login" unless current_user.admin?
  • 32.
    Methods (functions) aresimple too. # if start date + 6 months is > today def on_probation?(start_date) (start_date >> 6) > Date.today end
  • 33.
    Classes are easytoo. class Person @started_on = Date.today @name = "" def started_on=(date) @started_on = date end def started_on @started_on end end
  • 34.
    Class instance variablesare private class Person @started_on = Date.today Expose them through @name = "" accessor methods that def started_on=(date) @started_on = date resemble C# and VB end Property members. def started_on @started_on end person = Person.new person.age = 32 def name=(name) person.name = "Brian" @name = name end person.age => 32 def name person.name @name => "Brian" end end
  • 35.
    Let Ruby writecode for you! class Person @started_on = Date.today @name = "" def started_on=(date) class Person @started_on = date end attr_accessor :name attr_accessor :started_on def started_on @started_on end end def name=(name) @name = name end def name @name end end
  • 36.
    Ruby is aloaded gun. twitter: bphogan email: brianhogan at napcs.com
  • 37.
    So, write goodtests. twitter: bphogan email: brianhogan at napcs.com
  • 38.
  • 39.
    def test_user_hired_today_should_be_on_probation person = Person.new person.hired_on = Date.today assert person.on_probation? end test_user_hired_last_year_should_not_be_on_probation person = Person.new person.hired_on = 1.year.ago assert !person.on_probation? end
  • 40.
    Implement the method classPerson attr_accessor :name, :start_date def on_probation? (start_date >> 6) > Date.today end end
  • 41.
    And the testspass. twitter: bphogan email: brianhogan at napcs.com
  • 42.
    Testing first helpsyou think about your design AND your features. twitter: bphogan email: brianhogan at napcs.com
  • 43.
    Every professional Ruby developer writes tests first for production code. twitter: bphogan email: brianhogan at napcs.com
  • 44.
    Ten Simple Rules For Programming in My Favorite Language.
  • 45.
    1. Everything isan object twitter: bphogan email: brianhogan at napcs.com
  • 46.
    25.class Fixnum "brian".class String [1,2,3].class Array
  • 47.
    2. Everything evaluates to true except nil or false twitter: bphogan email: brianhogan at napcs.com
  • 48.
    x = 0 0 puts x if x x = -1 -1 puts x if x x = false nil puts x if x x = nil nil puts x if x
  • 49.
    3. Variables are dynamically typed but DATA is strongly typed! twitter: bphogan email: brianhogan at napcs.com
  • 50.
    age = 32 name= "Brian" TypeError: can't convert Fixnum into String name + age age = 32 name = "Brian" “Brian32” name + age.to_s
  • 51.
    4. Every method returns the last evaluation implicitly twitter: bphogan email: brianhogan at napcs.com
  • 52.
    def limit_reached? self.projects.length > 0 end def welcome_message if current_user.anonymous? "You need to log in." else "Welcome!" end end
  • 53.
    5. Every expression evaluates to an object twitter: bphogan email: brianhogan at napcs.com
  • 54.
    result = ifcurrent_user.anonymous? "You need to log in." else "Welcome!" end
  • 55.
    It is veryeasy to accidentally return false! def before_save if self.status == "closed" self.closed_on = Date.today end end
  • 56.
    6. Classes areobjects twitter: bphogan email: brianhogan at napcs.com
  • 57.
    WRONG! person = newPerson RIGHT! person = Person.new
  • 58.
    7. You needto use and understand blocks. twitter: bphogan email: brianhogan at napcs.com
  • 59.
    Blocks can iterate roles.eachdo |role| puts "<li>" + role.name + "<li>" end
  • 60.
    They can alsoencapsulate code. ActiveRecord::Schema.define do create_table :pages do |t| t.string :name t.text :body t.timestamps end end
  • 61.
    Every method cantake a block! 5.times do puts "Hello!" end
  • 62.
    8. Favor modulesover inheritance twitter: bphogan email: brianhogan at napcs.com
  • 63.
    module SharedValidations def self.included(base) base.validates_presence_of :name base.validates_uniqueness_of :name end end class Project class Task include SharedValidations include SharedValidations end end
  • 64.
    Do not usetype, use behaviors. twitter: bphogan email: brianhogan at napcs.com
  • 65.
  • 66.
    module Doctor module Ninja def treat_patient def attack puts "All better!" puts "You’re dead!" end end end end module Musician def play_guitar puts "meedily-meedily-meedily-meeeeeeeeee!" end end
  • 67.
    person = Person.new person.extendNinja "You're dead!" person.attack person.extend Doctor "All better!" person.treat_patient person.extend Musician "meedily-meedily- person.play_guitar meedily-meeeeeeeeee!"
  • 68.
    9. Embrace Reflection twitter:bphogan email: brianhogan at napcs.com
  • 69.
    person.respond_to?(:name) true person.respond_to?(:age) false person.send(:name) “Brian”
  • 70.
    10. Write codethat writes code. twitter: bphogan email: brianhogan at napcs.com
  • 71.
    class User ROLES = ["admin", "superadmin", "user", "moderator"] ROLES.each do |role| class_eval <<-EOF def #{role}? self.roles.include?("#{role}") end EOF end end user = User.new user.admin? user.moderator?
  • 72.
    haml and sass twitter:bphogan email: brianhogan at napcs.com
  • 73.
    HAML !!! #wrapper.container_12 #header.grid_12 %h1 The awesome site %ul#navbar.grid_12 %li %a{:href => "index.html"} Home %li %a{:href => "products"} Products %li %a{:href => "services"} Services #middle.grid_12 %h2 Welcome #footer.grid_12 %p Copyright 2009 SomeCompany
  • 74.
    HTML <div class='container_12' id='wrapper'> <div class='grid_12' id='header'> <h1>The awesome site</h1> </div> <ul class='grid_12' id='navbar'> <li> <a href='index.html'>Home</a> </li> <li> <a href='products'>Products</a> </li> <li> <a href='services'>Services</a> </li> </ul> <div class='grid_12' id='middle'> <h2>Welcome</h2> </div> <div class='grid_12' id='footer'> <p>Copyright 2009 SomeCompany</p> </div> </div>
  • 75.
    SASS !the_border = 1px !base_color= #111 #header color = !base_color * 3 border-left= !the_border border-right = !the_border * 2 color: red a font-weight: bold text-decoration: none
  • 76.
    CSS #header { color: #333333; border-left: 1px; border-right: 2px; color: red; } #header a { font-weight: bold; text-decoration: none; }
  • 77.
  • 78.
  • 79.
    Hello Sinatra! require 'rubygems' require'sinatra' get "/" do "Hello Sinatra!" end
  • 81.
    Sinatra demo twitter: bphogan email:brianhogan at napcs.com
  • 82.
  • 83.
    Feature: creating anew page in the wiki As an average anonymous user I want to create a page about Ruby So that I can tell everyone how awesome it is. Scenario: Creating a new page and editing its content Given I go to "/ruby" Then I should see "Edit this page" When I click "Edit this page" And I fill in "body" with "Ruby is the best programming language in the whole world!" And I press "Save" Then I should see "Ruby is the best programming language in the whole world!" twitter: bphogan email: brianhogan at napcs.com
  • 84.
    Testing the Wikiwith Webrat and Cucumber twitter: bphogan email: brianhogan at napcs.com
  • 85.
    Ruby will makeyou productive. twitter: bphogan email: brianhogan at napcs.com
  • 86.
    And happy. twitter: bphogan email:brianhogan at napcs.com
  • 87.
    Resources: Try Rubyin your browser! http://tryruby.sophrinix.com/ Try SASS online: http://sass-lang.com/try.html Try HAML online: http://haml-lang.com/try.html http://staticmatic.rubyforge.org/ Sinatra: http://www.sinatrarb.com/ Sinatra Wiki source: http://github.com/napcs/sinatriki Cucumber: http://cukes.info/ WATIR: http://watir.com/ twitter: bphogan email: brianhogan at napcs.com
  • 88.
    Questions? Twitter: bphogan brianhogan at napcs.com twitter: bphogan email: brianhogan at napcs.com

Editor's Notes

  • #2 Hi everyone. I&amp;#x2019;m Brian. I do Ruby and Rails training and consulting.
  • #4 Maybe you do... but it can be even more fun.
  • #5 I hated programming. I did some when I was a kid, but it wasn&amp;#x2019;t what I wanted to do. I liked the web. And I started building sites in 1995 for small businesses.
  • #6 so I started learning to program in ASP and eventually PHP. Even did some Java and some Oracle DBA stuff in there.
  • #7 I was getting burned out, spending hours fighting with the languages while writing the same kind of applications over again.
  • #8 A consultant who was working with me on a Java project introduced me to Rails and now, four years later,
  • #9 I get to work on fun projects, work with amazing people, I&amp;#x2019;m excited about what I do, and I even got to write some books.
  • #10 I want to get you excited about this language. I want to you to ask me any questions you have, and I want you to run home and start coding! So the best way to do that is to show you what you can do.
  • #11 We can make a desktop application that works on Windows, Mac, and Linux using Shoes.
  • #12 We can make a very simple iPhone-enabled website with Sinatra. This one serves files to you in around 50 lines of code.
  • #13 We can use Sass to generate stylesheets for our applications. We can use variables for our colors and widths!
  • #15 Use Rails. Rails is a great framework for building web applications. And despite what you&amp;#x2019;ve heard, it scales exceptionally well, as long as you know how to scale a web application and you&amp;#x2019;ve written good code.
  • #17 Use Rails to kickstart a CMS.
  • #18 Highly dynamic, high level, 100% object oriented, 100% open source, and really easy to learn.
  • #19 Ruby was created by Yukihiro Matsumoto (Matz) in 1993. It&amp;#x2019;s built on C, and has many implementations, including JRuby, which runs on the JVM, and IronRuby, which runs on the .Net platform.
  • #20 &amp;#x201C;How you feel is more important than what you do. &amp;#x201C; The entire language is designed for programmer productivity and fun.
  • #21 Principle of Least Surprise - This means The language should behave in a way that is not confusing to experienced developers. It doesn&amp;#x2019;t mean that it works like your current favorite language! But as you get used to Ruby, you&amp;#x2019;ll find that you ramp up quickly.
  • #22 Ruby achieves this through a consistant API. You won&amp;#x2019;t find yourself guessing too much what methods are available to you.
  • #23 It also helps that the syntax is simple. There are no unnecessary semicolons or curly braces. The interpreter knows when lines end.
  • #25 We have numbers, strings, multiplication, addition, subtraction, and division, just like everyone else.
  • #26 The square brackets denote an array.
  • #28 This is the hash symbol, or the hash rocket. Whenever you see this, you&amp;#x2019;re dealing with a hash.
  • #29 When you see these, you&amp;#x2019;re looking at Symbols. They represent names and some strings. They conserve memory, as repeating a symbol in your code uses the same memory reference, whereas repeating a string creates a new object on each use.
  • #31 Unless is an alias for &amp;#x201C;if not&amp;#x201D;. Subtle, but sometimes much more readable.
  • #32 You can append these suffixes to statements to prevent them from firing. This is a great space saver and it&amp;#x2019;s easy to read
  • #33 The two arrows (&gt;&gt;) is actually a method on the Date object that adds months. So here, we&amp;#x2019;re adding six months to the start date and comparing it to today Notice here that the input parameter is assumed to be a date. There&amp;#x2019;s no type checking here.
  • #35 The = is part of the method name. And Ruby&amp;#x2019;s interpreter doesn&amp;#x2019;t mind you putting a space in front of it to make it easier to read!
  • #36 Making getters and setters is so common that Ruby can do it for you.
  • #37 It assumes you are an intelligent person who wants to get things done. It will not try to protect you from your own stupidity.
  • #38 In fact,
  • #39 Test All The Effing Time! Let&amp;#x2019;s go through adding our &amp;#x201C;on_probation?&amp;#x201D; method to our Person class. A person is on probation for the first six months of employment.
  • #40 Here we have two tests, one using a person hired today, and another using a person last year.
  • #42 Did we miss any cases?
  • #47 Everything is an object in Ruby. There are no primitive types. Strings, integers, floats, everything. Even Nil, True, and False!
  • #49 Everything. Even 0 and -1.
  • #51 I&amp;#x2019;m not here to tell you that dynamically typed languages are better than statically typed languages. I prefer dynamic typing. I am more productive with it. And most of the claims against it are false.
  • #53 We don&amp;#x2019;t need to specify a &amp;#x201C;return&amp;#x201D; keyword.
  • #56 In this example, if the status is not closed, this method will return false. In Rails, if a before_save method returns false, the record won&amp;#x2019;t save to the database.
  • #60 There are methods on arrays and hashes to iterate over the elements stored within.
  • #61 Blocks let you pass code as a parameter, so that the code may be run within the method. If you&amp;#x2019;ve used closures or anonymous functions, you already understand this. But this is how Ruby developers work every day.
  • #63 We can create modules of code that we can mix in to our classes.
  • #64 In this example, we&amp;#x2019;re using modules to replace inheritence. However, since classes are objects, we can also apply modules to instances of objects at runtime.
  • #66 If it walks like a duck, and talks like a duck, it&amp;#x2019;s a duck. Even if it&amp;#x2019;s not.
  • #67 Declare modules that encapsulate behavior. Here we have a doctor, a ninja, and a musician.
  • #68 We can then mix in the behaviors to the instance of the class. Its type doesn&amp;#x2019;t really matter. We can ask the instance if it has the methods we want and we can call them.
  • #69 Reflection is built into the core language. It&amp;#x2019;s not a tacked on library, and it&amp;#x2019;s meant to be used to improve your code.
  • #70 We can ask our model all sorts of questions, and even actually send messages dynamically.
  • #72 We can loop over an array and generate methods on the object.
  • #80 Sinatra is a simple web framework that basically maps incoming requests to backend code that produces responses.
  • #81 That little bit of code gets us a working web application that handles requests.
  • #84 We write stories using plain text, that describes what we want to do.