SlideShare une entreprise Scribd logo
1  sur  182
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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
 

Tendances (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
 

Similaire à 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
 

Similaire à 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”
 

Plus de 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
 

Plus de 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
 

Dernier

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
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
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
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
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 

Dernier (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
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
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
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
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 

Ruby is Awesome