SlideShare ist ein Scribd-Unternehmen logo
1 von 182
Downloaden Sie, um offline zu lesen
Ruby is Awesome


          Vitaly Kushner
           astrails.com
Interesting Times
Fast, Good, or Cheap.
       Pick two.
Fast, Good, or Cheap.
       Pick two.
Change Environment
Choose Language
Good Enough
You can do almost
     anything
     with any
     language
http://www.flickr.com/photos/jantik/254695220/
Paul Graham
 http://paulgraham.com/
Blub Language Paradox
BASIC was
“Good Enough”
No Recursion?!
Beating the averages
 http://paulgraham.com/avg.html
Lisp is good
Ruby is Better!
      :-)
Ruby is Practical
Ruby is an acceptable
         LISP
History
History

• Yukihiro Matsumoto (aka "Matz")
History

• Yukihiro Matsumoto (aka "Matz")
• Released in 1993
History

• Yukihiro Matsumoto (aka "Matz")
• Released in 1993
• Got known in US about 2000
History

• Yukihiro Matsumoto (aka "Matz")
• Released in 1993
• Got known in US about 2000
• Gained momentum around 2003-2005
LISP
    +
Smalltalk
    +
 Python
    +
  Perl
• Simple consistent syntax
• Dynamically typed
• Late binding
• Single Inheritance with Mixin support
• Everything is an object
• Closures
• Garbage Collection
• Multi platform
Ruby is Awesome
Blocks
array.each { |e| puts }

array.each { |e| puts e}
  array.each do |e|
  puts e
end
map       {|x|   ...}
collect   {|x|   ...}
select    {|x|   ...}
reject    {|x|   ...}
find      {|x|   ...}
any?      {|x|   ...}
all?      {|x|   ...}
sort      {|a,   b| ...}
File.readlines("foobar.dat").map{|l| l.strip}.sort {|x,y| x[-1] <=> y[-1]}.map {|x| x.upcase}.to_xml
File.readlines("foobar.dat").map{|l| l.strip}.sort {|x,y| x[-1] <=> y[-1]}.map {|x| x.upcase}.to_xml




     File.readlines("foobar.dat")
File.readlines("foobar.dat").map{|l| l.strip}.sort {|x,y| x[-1] <=> y[-1]}.map {|x| x.upcase}.to_xml




     File.readlines("foobar.dat")

           .map {|line| line.strip}
File.readlines("foobar.dat").map{|l| l.strip}.sort {|x,y| x[-1] <=> y[-1]}.map {|x| x.upcase}.to_xml




     File.readlines("foobar.dat")

           .map {|line| line.strip}

                .sort {|x,y| x.to_i <=> y.to_i}
File.readlines("foobar.dat").map{|l| l.strip}.sort {|x,y| x[-1] <=> y[-1]}.map {|x| x.upcase}.to_xml




     File.readlines("foobar.dat")

           .map {|line| line.strip}

                .sort {|x,y| x.to_i <=> y.to_i}

                      .map {|x| x.upcase}
File.readlines("foobar.dat").map{|l| l.strip}.sort {|x,y| x[-1] <=> y[-1]}.map {|x| x.upcase}.to_xml




     File.readlines("foobar.dat")

           .map {|line| line.strip}

                .sort {|x,y| x.to_i <=> y.to_i}

                      .map {|x| x.upcase}

                           .to_xml
class Hash
  def to_html_attributes
    map { |k, v|
      k + '="' + v + '"'
    }.join(' ')
  end
end
attrs = {
  :src => "foo.img",
  :width => 100,
  :height => 200,
  :class => "avatar"
}
attrs.to_html_attributes
=> 'class="avatar" height="200" width="100" src="foo.img"'
Closures
class Array
  def has_any_bigger_then(x)
    any? {|e| e > x}
  end
end
def incrementor(x)
  proc {|y| y + x}
end

inc1 = incrementor(1)

inc5 = incrementor(5)
def incrementor(x)
  proc {|y| y + x}
end

inc1 = incrementor(1)

inc1.call(1)
=> 2
inc1.call(3)
=> 4
def incrementor(x)
  proc {|y| y + x}
end

inc5 = incrementor(5)

inc5.call(1)
=> 6
inc5.call(3)
=> 8
# ruby
def paidMore(amount)
  proc {|e| e.salary > amount}
end

// C#
public Predicate<Employee>
PaidMore(int amount) {
  return delegate(Employee e) {
    return e.Salary > amount;
  }
}
Meta Programming
Extending the language
    to create new
     abstractions
Monkey Patching
class Hash
  def to_html_attributes
    map { |k, v|
      k + '="' + v + '"'
    }.join(' ')
  end
end
attrs = {
  :src => "foo.img",
  :width => 100,
  :height => 200,
  :class => "avatar"
}
attrs.to_html_attributes
=> 'class="avatar" height="200" width="100" src="foo.img"'
3.megabytes
=> 3145728
10.months.from_now
=> Thu Aug 12 03:25:40 0300 2010
5.minutes.ago
=> Mon Oct 12 03:21:02 0200 2009
Duck Typing
.to_s

 [1, 2, 3].to_s
=> "123"
.to_s

123.to_s
=> "123"
.to_s

"123".to_s
=> "123"
"a#{b}c"

"a" + b.to_s + c
method_missing
NoMethodError
User.find_by_company("Astrails")
User.find_by_name_and_company(
   "Vitaly Kushner", "Astrails")
Multiple inheritance is evil
            :-)
Modules
 a.k.a. Mixins
module FlyHome
  def set_home
    @home = position
  end

  def fly_home
    fly(@home)
  end
end
class Bird < Living
  include FlyHome
  def fly(direction) ...
  def position ...
end

class Airplane < Machine
  include FlyHome
  def fly(direction) ...
  def position ...
end
DSL
Domain Specific Language
class User < ActiveRecord::Base
  has_many :projects
  belongs_to :account
  has_many :reports,
    :class_name => "User",
    :foreign_key => :reports_to_id
  named_scope :activated,
    :conditions =>
      "activated_at IS NOT NULL"
  validates_uniqueness_of :name
  validates_presence_of :crypted_password
  validates_acceptance_of :terms_of_service
end
safe do
  local { path "/backup/:kind" }
  s3 :key => YOUR_S3_KEY,
    :secret => YOUR_S3_SECRET,
    :bucket => S3_BUCKET,
    :path => ":kind/"
  gpg :password => "foobar"

 mysqldump do
   options "-ceKq --single-transaction --create-options"
   user "astrails"
   password "foobar"

    database :blog
    database :astrails_com do
      skip_tables :request_logs
    end
  end

 tar do
   archive "etc-files" do
     files "/etc"
   end
 end

end
safe do
  local { path "/backup/:kind" }
  s3 :key => YOUR_S3_KEY,
    :secret => YOUR_S3_SECRET,
    :bucket => S3_BUCKET,
    :path => ":kind/"
  gpg :password => "foobar"

  ...
end
safe do
  ...
  mysqldump do
    options "-ceKq ..."
    user "astrails"
    password "foobar"

    database :blog
    database :astrails_com do
      skip_tables :request_logs
    end
  end
  ...
end
safe do
  ...

  tar do
    archive "etc-files" do
      files "/etc"
    end
  end

end
Rubygems
➜

~

✗
sudo
gem
install
astrails‐safe
Successfully
installed
astrails‐safe‐0.2.3
1
gem
installed
Installing
ri
documentation
for
astrails‐safe‐0.2.3...
Installing
RDoc
documentation
for
astrails‐safe‐0.2.3...
➜

~

✗

Rubyforge.org
 8,426 gems
Github.com
7,483 gems
Rails
http://www.flickr.com/photos/ecstaticist/2589723846/
Rails is Fun
optimized for
programmers happiness
    and sustainable
      productivity
MVC
MVC

•   Model
MVC

•Model
• View
MVC

•Model
• View
• Controller
convention over
 configuration
class User < ActiveRecord::Base
end
User.find(123)
=> SELECT * FROM `users`   WHERE (`users`.`id` = 123)
class User < ActiveRecord::Base
  belongs_to :account
  has_many :projects
end

class UsersController < ApplicationController
  def show
    @user = User.find(params[:user])
    render :template => 'show'
  end
end
class User < ActiveRecord::Base
  belongs_to :account
  has_many :projects
end

class UsersController < ApplicationController
  def show
    @user = User.find(params[:user])
    render :template => 'show'
  end
end
class User < ActiveRecord::Base
  belongs_to :account
  has_many :projects
end

class UsersController < ApplicationController
  def show
    @user = User.find(params[:user])
  end
end
Models
http://www.flickr.com/photos/slyadnev/3959052112/
ActiveRecord
ORM
Object-Relational Mapping
• MySQL
• PostgreSQL
• MSSql
• SQLite
• Oracle
• ODBC
Associations
class User < ActiveRecord::Base
  has_many :projects
end

class Project < ActiveRecord::Base
  belongs_to :user
end
u = User.find(1)
=> SELECT * FROM `users`   WHERE (`users`.`id` = 1)
u.projects.count
=> SELECT count(*) AS count_all   FROM `projects` WHERE
(`projects`.user_id = 1)
User.find_by_first_name("Vitaly", :include => :projects)
=> SELECT * FROM `users` WHERE
  (`users`.`first_name` = 'Vitaly') LIMIT 1
=> SELECT `projects`.* FROM `projects` WHERE
  (`projects`.user_id = 1)
Project.first.user
=> SELECT * FROM `projects` LIMIT 1
=> SELECT * FROM `users` WHERE (`users`.`id`   = 1)
Callbacks
•   before_validation

•   before_validation_on_create

•   after_validation

•   after_validation_on_create

•   before_save

•   before_create

•   after_create

•   after_save
Callbacks
•   before_validation

•   before_validation_on_create

•   after_validation

•   after_validation_on_create

•   before_save

•   before_create

•   after_create

•   after_save
class User < ActiveRecord::Base
  before_save :encrypt_password
  attr_accessor :password
  private
  def enctypt_password
    unless password.blank?
      self.salt ||= ActiveSupport::SecureRandom.hex(40)
      self.crypted_password = encrypt(password, salt)
    end
  end
end
Validations
validates_presence_of :account_id
validates_uniqueness_of :name
validates_numericality_of :ccv

def validate
  unless name[0] == ?A
    errors.add(:name, "Names must start with an A")
  end
end
ActiveSupport
3.days.ago

[1,2,3].to_json

2.weeks.from_now

hash.slice(:foo, :bar)
Controllers
http://www.flickr.com/photos/benjamin-nagel/2902721172/
class UsersController < ApplicationController
  def index
    @users = User.paginate(:page => params[:page],
      :per_page => 20)
  end
end
http://yourdomain/users/index
http://localhost:3000/users/index
ActionController::Routing::Routes.draw do |map|
    map.connect ':controller/:action/:id'
    map.connect ':controller/:action/:id.:format'
end
ActionController::Routing::Routes.draw do |map|
    map.connect ':controller/:action/:id'
    map.connect ':controller/:action/:id.:format'
end




   /welcome/home
       :controller => 'welcome'

       :action => 'home'
ActionController::Routing::Routes.draw do |map|
    map.connect ':controller/:action/:id'
    map.connect ':controller/:action/:id.:format'
end




   /users/edit/123
       :controller => 'users'

       :action => 'edit'

       :id => '123'
ActionController::Routing::Routes.draw do |map|
    map.connect ':controller/:action/:id'
    map.connect ':controller/:action/:id.:format'
end




   projects/show/456.xml
       :controller => 'projects'

       :action => 'show'

       :id => '456'

       :format => 'xml'
/talks/create?title=ruby%20is%20awsome&author[name]=Vitaly&author[company]=Astrails




          {
          :controller => 'talks',
          :action => 'create',
          :title => "ruby is awesome",
          :user => {
            :name => 'Vitaly',
            :company => 'Astrails'
          }
      }
REST
REST
Representational State Transfer
• HEAD
• GET
• POST
• PUT
• DELETE
•   index
             •   edit
•   new
             •   update
•   create
             •   destroy
•   show
index


GET /users
new


GET /users/new
create


POST /users
show


GET /users/123
edit


GET /users/123/edit
update


PUT /users/123
destroy


DELETE /users/123
map.resources :users do |user|
  user.resources :projects
end




  GET /users/123/projects
     :controller => :projects, :action => :index, :user_id => 123

  GET /users/123/projects/456
     :controller => :projects, :action => :show, :user_id => 123, :id => 456
users_path
=> /users
new_user_path
=> /users/new
user_path(user)
=> /users/123
edit_user_path(user)
=> /users/123/edit
Filters
class UsersController < ApplicationController
  before_filter :login_required,
    :except => [:new, :create]
  before_filter :find_user,
    :only => [:edit, :show, :update, :destroy]

  def   index ...
  def   new ...
  def   create ...
  def   edit ...
  def   show ...
  def   update ...
  def   destroy ...

protected
  def login_required ...

  def find_user ...
end
class UsersController < ApplicationController
  before_filter :login_required,
    :except => [:new, :create]
  ...
protected
  def login_required
    unless session[:user_id]
      redirect_to "/login"
    end
  end
end
class UsersController < ApplicationController
  before_filter :find_user,
    :only => [:edit, :show, :update, :destroy]
  ...
protected
  def find_user
    @user = User.find(params[:id])
  end
end
def index
  @users = User.paginate(
    :page => params[:page], :per_page => 20)
end
def new
  @user = User.new(params[:user])
end
def create
  @user = User.new(params[:user])
  if @user.save
    flash[:notice] = "User created"
    redirect_to user_path(@user)
  else
    flash.now[:error] = "Failed to create a user"
    render :action => "new"
  end
end
def edit
end
def show
end
def update
  if @user.update_attributes(params[:user])
    flash[:notice] = "User updated"
    redirect_to user_path(@user)
  else
    flash.now[:error] = "Failed to update user"
    render :action => "edit"
  end
end
def destroy
  if @user.destroy
    flash[:notice] = "User deleted"
  else
    flash[:error] = "Failed to delete user"
  end
  redirect_to users_path
end
Errors
class UsersController < ApplicationController
  before_filter :find_user,
    :only => [:edit, :show, :update, :destroy]
  ...
  def update
    if @user.update_attributes(params[:user])
      ...
    end
  end
protected
  def find_user
    @user = User.find(params[:id])
  end
end
ActiveRecord::RecordNotFound
HTTP 404
HTTP 500
Session
Session Store

• files
• database
• cookie
class UserSessionController < ApplicationController
  def create
    unless user = User.authenticate(
                      params[:login], params[:password])
      flash.now[:error] = "Login failed"
      render :action => :new
	 	   return
    end

    session[:user_id] = user.id
    redirect_to user_path(user)
  end
end
MVC
Views
http://www.flickr.com/photos/brapke/226101874/
def index
  @users = User.paginate(
    :page => params[:page], :per_page => 20)
end
app/views/users/index.html.erb
ERB




<p>
  Hello <%= h(@user.name) %>
</p>
ERB




<ul>
  <% @user.projects.each do |project| %>
    <li><%= h(project.name) %></li>
  <% end %>
<ul>
def index
  @users = User.paginate(...)
  respond_to do |format|
    # default action is to render index.html.erb
    format.html
    format.xml { @users.to_xml }
    format.json { @users.to_json }
  end
end
HAML



%p
     = @user.name

%ul
  - @user.projects.each do |project|
    %li= project.name
Testing
TDD
TDD
Test Driven Development
BDD
BDD
Behavior Driven Development
Pressure
TATFT
TATFT
Test All The Fucking Time
• Test::Unit
• RSpec
• Shoulda
• Cucumber
• Webrat
it "should be able to show media" do
  @media = stub_media
  Media.stub!(:find).and_return(@media)
  get :show, :id => @media.id
  response.should be_success
end
Migrations
class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.integer :user_id, :null => false
      t.string :title, :null => false
      t.text :description, :null => false
      t.integer :budget, :null => false

      t.timestamps
    end
  end

  def self.down
    drop_table :projects
  end
end
Plugins
inherited_resourfce
standard implementation for the 7 REST actions
acts_as_tree
db schema and methods for storing trees
country_select
HTML helper to present a select box of countries
Rails Scales?
http://www.flickr.com/photos/pinksherbet/223270526/
Rails Scales?
  YES
LinkedIn’s “Bumper Sticker”
  More then billion page views per month
if you have no
scalability problems
  you are not growing fast enough!
Ruby is Awesome
    Q &A
          Vitaly Kushner
           astrails.com

Weitere ähnliche Inhalte

Was ist angesagt?

Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma IntroduçãoÍgor Bonadio
 
[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기NAVER D2
 
Designing with malli
Designing with malliDesigning with malli
Designing with malliMetosin Oy
 
A comparison between C# and Java
A comparison between C# and JavaA comparison between C# and Java
A comparison between C# and JavaAli MasudianPour
 
Malli: inside data-driven schemas
Malli: inside data-driven schemasMalli: inside data-driven schemas
Malli: inside data-driven schemasMetosin Oy
 
Clojutre Real Life (2012 ClojuTRE Retro Edition)
Clojutre Real Life (2012 ClojuTRE Retro Edition)Clojutre Real Life (2012 ClojuTRE Retro Edition)
Clojutre Real Life (2012 ClojuTRE Retro Edition)Metosin Oy
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With ClojureMetosin Oy
 
Node meetup feb_20_12
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12jafar104
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperosfameron
 
HTML5 Canvas - The Future of Graphics on the Web
HTML5 Canvas - The Future of Graphics on the WebHTML5 Canvas - The Future of Graphics on the Web
HTML5 Canvas - The Future of Graphics on the WebRobin Hawkes
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecordscalaconfjp
 

Was ist angesagt? (20)

Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
 
Lenses
LensesLenses
Lenses
 
[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기
 
7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
Designing with malli
Designing with malliDesigning with malli
Designing with malli
 
A comparison between C# and Java
A comparison between C# and JavaA comparison between C# and Java
A comparison between C# and Java
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Malli: inside data-driven schemas
Malli: inside data-driven schemasMalli: inside data-driven schemas
Malli: inside data-driven schemas
 
Clojutre Real Life (2012 ClojuTRE Retro Edition)
Clojutre Real Life (2012 ClojuTRE Retro Edition)Clojutre Real Life (2012 ClojuTRE Retro Edition)
Clojutre Real Life (2012 ClojuTRE Retro Edition)
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
 
Node meetup feb_20_12
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipper
 
HTML5 Canvas - The Future of Graphics on the Web
HTML5 Canvas - The Future of Graphics on the WebHTML5 Canvas - The Future of Graphics on the Web
HTML5 Canvas - The Future of Graphics on the Web
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
 
PHP 1
PHP 1PHP 1
PHP 1
 

Ähnlich wie Ruby is Awesome

Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable LispAstrails
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperJon Kruger
 
Go Web Development
Go Web DevelopmentGo Web Development
Go Web DevelopmentCheng-Yi Yu
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovyIsuru Samaraweera
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05cKaz Yoshikawa
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
ELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardGeorg Sorst
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQLPeter Eisentraut
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) RoundupWayne Carter
 
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
Rapid and Scalable Development with MongoDB, PyMongo, and MingRapid and Scalable Development with MongoDB, PyMongo, and Ming
Rapid and Scalable Development with MongoDB, PyMongo, and MingRick Copeland
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 

Ähnlich wie Ruby is Awesome (20)

Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable Lisp
 
DataMapper
DataMapperDataMapper
DataMapper
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
Go Web Development
Go Web DevelopmentGo Web Development
Go Web Development
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
 
ELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboard
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQL
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
 
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
Rapid and Scalable Development with MongoDB, PyMongo, and MingRapid and Scalable Development with MongoDB, PyMongo, and Ming
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 

Mehr von Astrails

Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applicationsAstrails
 
Accounting For Hackers
Accounting For HackersAccounting For Hackers
Accounting For HackersAstrails
 
Machine Learning: Make Your Ruby Code Smarter
Machine Learning: Make Your Ruby Code SmarterMachine Learning: Make Your Ruby Code Smarter
Machine Learning: Make Your Ruby Code SmarterAstrails
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
Engineering esthetics
Engineering estheticsEngineering esthetics
Engineering estheticsAstrails
 
Lean Software Development
Lean Software DevelopmentLean Software Development
Lean Software DevelopmentAstrails
 
RubyMotion: Put your Dreams in Motion with Ruby
RubyMotion: Put your Dreams in Motion with RubyRubyMotion: Put your Dreams in Motion with Ruby
RubyMotion: Put your Dreams in Motion with RubyAstrails
 
WTF is NoSQL
WTF is NoSQLWTF is NoSQL
WTF is NoSQLAstrails
 
Cassandra intro
Cassandra introCassandra intro
Cassandra introAstrails
 
Rails missing features
Rails missing featuresRails missing features
Rails missing featuresAstrails
 
Performance - When, What and How
Performance - When, What and HowPerformance - When, What and How
Performance - When, What and HowAstrails
 

Mehr von Astrails (11)

Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
 
Accounting For Hackers
Accounting For HackersAccounting For Hackers
Accounting For Hackers
 
Machine Learning: Make Your Ruby Code Smarter
Machine Learning: Make Your Ruby Code SmarterMachine Learning: Make Your Ruby Code Smarter
Machine Learning: Make Your Ruby Code Smarter
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
Engineering esthetics
Engineering estheticsEngineering esthetics
Engineering esthetics
 
Lean Software Development
Lean Software DevelopmentLean Software Development
Lean Software Development
 
RubyMotion: Put your Dreams in Motion with Ruby
RubyMotion: Put your Dreams in Motion with RubyRubyMotion: Put your Dreams in Motion with Ruby
RubyMotion: Put your Dreams in Motion with Ruby
 
WTF is NoSQL
WTF is NoSQLWTF is NoSQL
WTF is NoSQL
 
Cassandra intro
Cassandra introCassandra intro
Cassandra intro
 
Rails missing features
Rails missing featuresRails missing features
Rails missing features
 
Performance - When, What and How
Performance - When, What and HowPerformance - When, What and How
Performance - When, What and How
 

Kürzlich hochgeladen

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Kürzlich hochgeladen (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Ruby is Awesome