SlideShare una empresa de Scribd logo
1 de 182
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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
 

Similar a 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
 

Similar a 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”
 

Más 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
 

Más 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
 

Último

Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 

Último (20)

Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

Ruby is Awesome