SlideShare a Scribd company logo
1 of 117
UPGRADINGTO RAILS 3
Changing the wheels on the bus at 80mph
(or 128.784 kph for everyone else)
Andrew Bloomgarden Julian Giuca
Andrew introduction
Andrew Bloomgarden
@aughr
2
Julian Giuca
@juliangiuca
3
Julian Giuca
@juliangiuca
3
Julian Giuca
@juliangiuca
3
Julian Giuca
@juliangiuca
3
4
Overview
5
You can dual boot
Rails 2 and Rails 3
Do try this at home!
6
Let’s talk about numbers...
7
Rails versions in the wild
2.x.x 3.x.x
8
Numberofaccounts
2.2.2# 2.2.3# 2.3.2# 2.3.4# 2.3.5# 2.3.8# 2.3.10# 2.3.11# 2.3.12# 2.3.14# 2.3.15# 3.0.1# 3.0.3# 3.0.5# 3.0.11# 3.0.15# 3.0.18# 3.0.19# 3.1.1# 3.2.1# 3.2.8# 3.2.11# 3.2.13#
Rails versions with >1 server
2.x.x 3.x.x
Numberofaccounts
Rails version vs number of server
10
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
11
Putting it off
Rearchitecting the app first
Do it all in a big spike!
Have a ruby_19 branch
STUPID THINGS WE TRIED
12
Rails 3? Why now?
13
Rails 3? Why now?
Someone will make upgrading
easier soon!
13
Rails 3? Why now?
Someone will make upgrading
easier soon!
Oh man, this is going to
be awful.
13
Gems are leaving us behind
14
Gems are leaving us behind
14
Come and work on
our Rails 2.3 app!
15
16
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
17
A bit of history
18
A bit of history
Move to Rails 2.0.1
18
A bit of history
18
A bit of history
Rails 2.3.14
70,000 application LOC
59,000 test LOC
18
Don’t break the world
19
Keep everyone happy
not this
thisthis
this
20
Keep ourselves happy
CONFLICT (content): …
CONFLICT (content): …
CONFLICT (content): …
⋮
CONFLICT (content): …
Automatic merge failed; fix conflicts
and then commit the result.
21
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
22
23
24
I’m looking at you Rails 1.2.2 people
25
I’m looking at you Rails 1.2.2 people
25
Gemfile
platforms :ruby_18 do
gem 'ruby-debug'
end
platforms :ruby_19 do
gem 'debugger'
end
26
27
Monkey patched!
27
In the Gemfile
if ENV.include?("USE_RAILS_3")
class Bundler::Dsl
if !self.method_defined?(:to_definition_without_rails3_lockfile)
alias_method :to_definition_without_rails3_lockfile, :to_definition
end
def to_definition(old_lockfile, unlock)
current = File.expand_path(Dir.pwd)
filename = File.join(current, "Gemfile_rails3.lock")
lockfile = Pathname.new(filename)
to_definition_without_rails3_lockfile(lockfile, unlock)
end
end
module Bundler::SharedHelpers
def default_lockfile
current = File.expand_path(Dir.pwd)
filename = File.join(current, "Gemfile_rails3.lock")
lockfile = Pathname.new(filename)
Pathname.new(lockfile)
end
end
end
28
Two Gemfile.lock files
29
Gemfile
if is_rails3
gem 'rails', '3.0.19'
gem 'lighthouse-api', '~>2.0.0'
gem 'dalli', '~> 2.3.0'
gem 'jquery-rails', '~>2.1'
gem 'active_reload'
else
gem 'rails', '2.3.15'
gem 'lighthouse-api', '~>1.1.0'
gem 'dalli', '~> 1.0.4'
end
30
# Booting in Rails 3 mode
$ export USE_RAILS_3=true
$ bundle install
$ rails server
31
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
32
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
Improved!
32
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
33
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
34
Make it easy for everyone
# Rails 2
$ script/server
# Rails 3
$ script/server3
35
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
36
Onto master
1. Boot Rails 3
2. Dual boot
3. Unbreak Rails 2
4. Merge upstream
37
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Restore Rails 2
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Restore Rails 2
Onto master
1. Boot Rails 3
2. Dual boot
3. Unbreak Rails 2
4. Merge upstream
39
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
40
Dual-booting that works
Rails 2.3 Rails 3
config/boot.rb requires Rails requires Bundler
config/environment.rb
loads, configures,
and initializes the
app
initializes the app
config/application.rb doesn’t exist
loads and
configures the app
41
Dual-booting that works
Rails 2.3 Rails 3
config/boot.rb requires Rails requires Bundler
config/environment.rb
loads, configures,
and initializes the
app
initializes the app
config/application.rb doesn’t exist
loads and
configures the app
41
Just make it work
42
config/boot.rb
if ENV.include?("USE_RAILS_3")
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||=
File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
43
else
# 123 lines that load Rails
# All that for this:
Rails.boot!
end
config/boot.rb
if ENV.include?("USE_RAILS_3")
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||=
File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
43
else
# 123 lines that load Rails
# All that for this:
Rails.boot!
end
config/boot.rb
if ENV.include?("USE_RAILS_3")
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||=
File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
43
else
# 123 lines that load Rails
# All that for this:
Rails.boot!
end
config/environment.rb
# Load the rails application
require_relative "application"
if CoreAppConfig.is_rails3?
# Initialize the rails application
RpmSite::Application.initialize!
end
44
config/application.rb
module NewRelicApplicationConfig
def self.rails3_config(config)
# Do Rails 3 stuff
common_config(config)
end
def self.rails2_config(config)
# Do Rails 2 stuff
common_config(config)
end
def self.common_config(config)
# ...
end
end
45
config/application.rb
46
if is_rails3
require 'rails/all'
Bundler.require(:default, Rails.env)
module RpmSite
class Application < Rails::Application
::NewRelicApplicationConfig.rails3_config(config)
end
end
else
Rails::Initializer.run do |config|
::NewRelicApplicationConfig.rails2_config(config)
end
end
config/application.rb
46
if is_rails3
require 'rails/all'
Bundler.require(:default, Rails.env)
module RpmSite
class Application < Rails::Application
::NewRelicApplicationConfig.rails3_config(config)
end
end
else
Rails::Initializer.run do |config|
::NewRelicApplicationConfig.rails2_config(config)
end
end
config/application.rb
46
if is_rails3
require 'rails/all'
Bundler.require(:default, Rails.env)
module RpmSite
class Application < Rails::Application
::NewRelicApplicationConfig.rails3_config(config)
end
end
else
Rails::Initializer.run do |config|
::NewRelicApplicationConfig.rails2_config(config)
end
end
Have tests you trust
47
Use CI
48
Upgrade dependencies on master
49
BackgroundJob to Resque
Bj.submit 'script/background/do_something.rb',
:email => DEV_TEAM
50
Never again
def getopts opts = {}
if RUBY_VERSION.to_f >= 1.9
# In 1.9 this throw/catch/getopts nonsense breaks
lambda do |*args|
keys, default, ignored = args
[keys].flatten.each do |key|
[key, key.to_s, key.to_s.intern].each do |key|
return opts[key] if opts.has_key?(key)
end
end
return default
end
else # In 1.8 you can't return across threads
lambda do |*args|
keys, default, ignored = args
catch('opt') do
[keys].flatten.each do |key|
[key, key.to_s, key.to_s.intern].each do |key|
throw 'opt', opts[key] if opts.has_key?(key)
end
end
default
end
end
end
end
51
Add an abstraction layer
Bj.submit 'script/background/do_something.rb',
:email => DEV_TEAM
52
Add an abstraction layer
Async::Command.new(
'script/background/do_something.rb'
).notify(DEV_TEAM).enqueue
52
Use Resque or BackgroundJob
class Async::Command < Async::Job
if CoreAppConfig.use_resque?
include Async::ResqueJob
extend Resque::Plugins::History
else
include Async::BjJob
end
# ...
end
53
Finally, use Resque
54
Branch by abstraction
55
The problem being with feature
branches is that the current state of
any one of them might be unable to
be deployed for a number of weeks
while the team gets it right.Those
branches just end up running and
running ….
– Paul Hammant
Branch by abstraction
55
Branch by abstraction: a pattern
for making large-scale changes to your
application incrementally on mainline.
– Jez Humble
Punt when you can56
ActiveSupport::Deprecation.silenced = true
57
Your old routes still work
RpmSite::Application.routes.draw do |map|
Jammit::Routes.draw(map)
# ...
end
58
Your old routes still work
RpmSite::Application.routes.draw do |map|
Jammit::Routes.draw(map)
# ...
end
58
Your old mailers still work
class AccountMailer < ApplicationMailer
def new_account(account, user, subscription)
headers['Errors-to'] = BOUNCE_ACCOUNT
from BILLING_ACCOUNT
subject "New Relic invoice account request"
recipients INVOICE_RECIPIENT
@account = account
@user = user
@subscription = subscription
end
end
59
Your old mailers still work
class AccountMailer < ApplicationMailer
def new_account(account, user, subscription)
headers['Errors-to'] = BOUNCE_ACCOUNT
from BILLING_ACCOUNT
subject "New Relic invoice account request"
recipients INVOICE_RECIPIENT
@account = account
@user = user
@subscription = subscription
end
end
59
Your old models (can) still work
self.store_full_sti_class = false
60
Your old views (can) still work
helper PrototypeHelper
clear_helpers
61
Your error handling (can) still work
# included into ApplicationController
def rescue_with_handler(e)
if super # ActiveSupport::Rescuable
true
else
rescue_action_in_public e
true
end
end
62
Temporarily ugly
63
if CoreAppConfig.is_rails3?
# do something
else
# do something else
end
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
64
We wantYOU to test!
65
To run in Rails 3, just run
script/server3
Extensive manual testing
66
DatabaseData collection
UI
Rails 3 UI
Make everyone a tester
67
Turn on Rails 3 by default
-is_rails3 = ENV.include?("USE_RAILS_3")
+is_rails3 = !ENV.include?("USE_RAILS_2")
68
Incompatible sessions
69
ActionDispatch::Session::SessionRestoreError
(Original exception: uninitialized constant
ActionController::Flash::FlashHash)
Incompatible sessions
69
Deploy a canary
70
Pause the world
71
Deploy all the servers
72
Oops
73
74
And we’re done!
75
And we’re done!
75
A few very tiny fires
76
Breaking the audit trail
ActionController::Base.class_eval do
cache_sweeper :audit_sweeper
end
Audit.add_observer(AuditSweeper.instance)
class AuditSweeper < ActionController::Caching::Sweeper
observe Audit
end
77
Rushed Resque rollout
78
Punching ActiveScaffold in the face
.../bundle/ruby/1.9.1/gems/
active_scaffold-3.0.26/lib/
active_scaffold/bridges/date_picker/
lib/datepicker_bridge.rb:127:in
`binread':
No such file or directory - .../public/
javascripts/active_scaffold/default/
date_picker_bridge.js (Errno::ENOENT)
79
Lost BackgroundJob instrumentation
This page left intentionally blank
80
Tagging green build off of Rails 2 tests
81
Lots of cleanup
82
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
83
Lessons learned
1. Preorder the donuts your on-call engineers like
2. Deprecate ActiveScaffold
3. Schedule lots of time for firefighting and cleanup
84
•Get it into master as early as possible
•Incremental everything
•CI is your bestest childhood friend
(and you secretly have a crush on them)
The special magic pony sauce
85
newrelic.com/rails3_upgrade@aughr | @juliangiuca
86
We’re done (and we’re hiring)

More Related Content

What's hot

What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPANcharsbar
 
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...Puppet
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersConnor McDonald
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Guillaume Laforge
 
Exploit techniques - a quick review
Exploit techniques - a quick reviewExploit techniques - a quick review
Exploit techniques - a quick reviewCe.Se.N.A. Security
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Guillaume Laforge
 
"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In SantosFabio Akita
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScriptMosky Liu
 
Zend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationZend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationRalf Eggert
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015qmmr
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)Robert Swisher
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalkHiroshi SHIBATA
 

What's hot (20)

What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
 
test
testtest
test
 
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX Developers
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
 
Bash 4
Bash 4Bash 4
Bash 4
 
Exploit techniques - a quick review
Exploit techniques - a quick reviewExploit techniques - a quick review
Exploit techniques - a quick review
 
Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012
 
Mona cheatsheet
Mona cheatsheetMona cheatsheet
Mona cheatsheet
 
"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScript
 
Gevent rabbit rpc
Gevent rabbit rpcGevent rabbit rpc
Gevent rabbit rpc
 
Zend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationZend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next Generation
 
Cooking pies with Celery
Cooking pies with CeleryCooking pies with Celery
Cooking pies with Celery
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalk
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 

Similar to Upgrading to Rails 3

Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
DeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latestDeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latestAtifkhilji
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloManageIQ
 
Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)yarry
 
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013Puppet
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst TipsJay Shirley
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manormartinbtt
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyNikhil Mungel
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...Matt Gauger
 
Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
Jedi Mind Tricks for Git
Jedi Mind Tricks for GitJedi Mind Tricks for Git
Jedi Mind Tricks for GitJan Krag
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplosvinibaggio
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725miguel dominguez
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725MortazaJohari
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Yevgeniy Brikman
 

Similar to Upgrading to Rails 3 (20)

Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
DeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latestDeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latest
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
 
Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)
 
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Speedy TDD with Rails
Speedy TDD with RailsSpeedy TDD with Rails
Speedy TDD with Rails
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst Tips
 
Porting to Python 3
Porting to Python 3Porting to Python 3
Porting to Python 3
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manor
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in Ruby
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Jedi Mind Tricks for Git
Jedi Mind Tricks for GitJedi Mind Tricks for Git
Jedi Mind Tricks for Git
 
Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
 

Recently uploaded

Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
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
 

Recently uploaded (20)

Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
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
 

Upgrading to Rails 3