http://slides.com/kyrrehavikeriksen/cdu14-ruby/live

http://bit.ly/1zQNUh7

Ruby
Sinatra.rb
Haml

Agenda

  • Om Ruby
  • Sinatra.rb
  • Haml

That's me...

Hva er ruby

Skapt av Yukihiro “Matz” Matsumoto i 1995.
Stable release    2.1.4 / October 27, 2014.

Hva bygger ruby på?

PERL

print "Hello World\n";

SMALLTALK

Transcript show: 'Hello, world!'.

EIFFEL

class
    HELLO_WORLD
create
    make
feature
    make
        do
            print ("Hello, world!%N")
        end
end

ADA

with Ada.Text_IO;
 
procedure Hello_World is
 use Ada.Text_IO;
begin
    Put_Line("Hello, world!");
end;

LISP

(princ "Hello, world!")

Matz, speaking on the Ruby-Talk mailing list, May 12th, 2000.

Ruby is simple in appearance, but is very complex inside, just like our human body

5.times { print "We *love* Ruby -- it's outrageous!" }

Alt er objekter

class Numeric
  def plus(x)
    self.+(x)
  end
end

y = 5.plus 6
# y is now equal to 11

Quirk #1

Seattle Style

puts array.delete hash.fetch :foo

Parenteser er valgfritt

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end
class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?()
      can(:manage, :all)
    else
      can(:read, :all)
    end
  end
end
 var # could be a local variable.
@var # is an instance variable.
$var # is a global variable.

a = [1,2,3]
b = [1,2,3]
a == b # true

foo = Foo.new("hi")
bar = Foo.new("you!")

foo.equals? bar # false

x = "3"
y = x + "ho!" #result: "3ho!"

y = x + 3 #Wooo! Ruby won't like that

y = x + 3.to_s #Woho! result: "33"

Dynamically & strongly typed

Quirk #2

c = class C  
end
# c == nil

Alt har retur verdi

x = 7  
(1..3).each do |x|
    p x
end
# => 3

Frustrasjon #1

We got

closure

class SomeClass
  def initialize(value1)
    @value1 = value1
  end
 
  def value_printer(value2)
    lambda {puts "Value1: #{@value1}, Value2: #{value2}"}
  end
end
 
def caller(some_closure)
  some_closure.call
end
 
some_class = SomeClass.new(5)
printer = some_class.value_printer("some value")
 
caller(printer)

Quirk #3

Standardverdier som parameter

def sum(a = 1, b = 2, c = 3)
    a + b + c
end

sum 3, 3
=> 9

sum
=> 6

def tables(t = {})
    puts t
end

tables(absolute: true, round: true, precision: 2)
=> "{:absolute=>true, :round=>true, :precision=>2}"

Single inheritance

class MyArray
  include Enumerable
end

class Publication
  attr_accessor :publisher
end

class Magazine < Publication
  attr_accessor :editor
end

m = Magazine.new
m.publisher = "Time Inc."

m.is_a? Magazine #=> true
m.is_a? Publication #=> true
m.class == Publication #=> false

Quirk #4

x = true
y = x || 2
=> # y == 2

x = nil || y
=> # x == 2

# alt er som nevnt objekter
x = nil
def nil.quack
    puts "quack quack" 
end

x.quack
=> quack quack

Kun "false" og "nil" er false

When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck

# p036duck.rb
class Duck
  def quack
    'Quack!'
  end
  
  def swim
    'Paddle paddle paddle...'
  end
end

class Goose
  def honk
    'Honk!'
  end
  def swim
    'Splash splash splash...'
  end
end

class DuckRecording
  def quack
    play
  end
  
  def play
    'Quack!'
  end
end

def make_it_quack(duck)
  duck.quack
end
puts make_it_quack(Duck.new)
puts make_it_quack(DuckRecording.new)

def make_it_swim(duck)
  duck.swim
end
puts make_it_swim(Duck.new)
puts make_it_swim(Goose.new)

Frustrasjon #2

expand = defined?( expand ) ? expand : true

if !defined?(expand) then; expand = true; end

expand = expand || true

expand ||= true
def foo(x)
 return x, x+1
end

a, b = foo (10)
#=> [10, 11]

Multippel returverdi

Put this in
your pipe

require 'sinatra'
get '/hi' do
  "Hello World!"
end

and smoke it

$ gem install sinatra
$ ruby hi.rb
== Sinatra has taken the stage ...
>> Listening on 0.0.0.0:4567

Hva er Sinatra?

domene spesifikt språk for å effektivt lage nettapplikasjoner

get '/hello/:name' do
  "Hello #{params[:name]}!"
end

get '/hello/:name' do |n|
  "Hello #{n}!"
end

get '/posts' do
  # matches "GET /posts?title=foo&author=bar"
  title = params[:title]
  author = params[:author]
end
get '/' do
  haml :index, :format => :html5
end

eller

set :haml, :format => :html5

get '/' do
  haml :index
end

Error-handling

not_found do
  'This is nowhere to be found.'
end

error 403 do
  'Access forbidden'
end

error MyCustomError do
  'So what happened was...' + env['sinatra.error'].message
end

get '/' do
  raise MyCustomError, 'something bad'
end

Sessions

enable :sessions

get '/' do
  "value = " << session[:value].inspect
end

get '/:value' do
  session[:value] = params[:value]
end

# litt mer avansert
use Rack::Session::Cookie, :key => 'rack.session',
                           :domain => 'foo.com',
                           :path => '/',
                           :expire_after => 2592000,
                           :secret => 'change_me',
                           :old_secret => 'also_change_me'

Haml is like a Zen garden and ERB is like crossing Broadway at rush hour in the rain

internett

Beautiful, DRY,
well-indented, clear markup:
templating haiku.

<section class=”container”>
  <h1><%= post.title %></h1>
  <h2><%= post.subtitle %></h2>
  <div class=”content”>
    <%= post.content %>
  </div>
</section>
%section.container
  %h1= post.title
  %h2= post.subtitle
  .content
    = post.content

ERB

HAML

<strong class="code" id="message">Hello, World!</strong>
%strong{:class => "code", :id => "message"} Hello, World!
%strong.code#message Hello, World!
<div class='content'>Hello, World!</div>
.content Hello, World!
!!!
%html
  %head
    %title Ciber Developer Update
    = haml :"templates/header_imports"
  %body
    = haml :"templates/nav"
    .container
      %h3
        Forslag til CDU 2014
      .row
        - get_suggestions.each do | key, suggestion |
          - data = {
                    :key => key,
                    :value => suggestion,
                    :delete => false
                   }
          =haml :"templates/suggestion", :locals => data
%div.suggestion{:style => "background: #eee;"}
  - if delete then
    %a{:href => "/stats/suggestions/delete?id=#{key}",
        :class => "pull-right"}
      Slett
  %strong
    #{value["title"]}
  %br
  = value["description"].gsub(/\r\n/, "<br>")
  %br
  %br
  %strong Format:
  #{value["format"]}
  %br
  %strong Track:
  #{value["track"]}
  %br
  %strong Ansvarlig:
  #{value["responsible"]}
  %br
.padding

Ruby foredrag

By Kyrre Havik

Ruby foredrag

  • 242