SlideShare a Scribd company logo
Upgrading to Ruby 2.x 
Joe Rafaniello 
@jrafanie
2007
13
Agenda 
1. History 
2. Why upgrade? 
3. Ruby 2.1 
4. Ruby 2.0 
5. "Fall cleanup" of old code 
6. Slow tests 
7. Building 2.0 appliances 
8. Developer setup 
9. Links 
10. Questions?
History 
Tue Nov 1 2011: 
First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ
History 
Tue Nov 1 2011: 
First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ 
Tue Apr 23 2013: 
Ruby 1.9.3 finally...
History 
Tue Nov 1 2011: 
First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ 
Tue Apr 23 2013: 
Ruby 1.9.3 finally... 
540 days???
History 
Tue Nov 1 2011: 
First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ 
Tue Apr 23 2013: 
Ruby 1.9.3 finally... 
540 days??? 
Lesson learned: Don't wait to upgrade!
Why upgrade?
Why upgrade? 
We're behind!!! 
Ruby 1.9.3 is ending 
In maintenance until February 23, 2014 
Security only mode until February 23, 2015 
Ruby 2.0.0 is nearly 20 months old 
Ruby 2.1.0 is nearly 10 months old 
Ruby 2.2.0 is scheduled for a Christmas release
Why upgrade? ... Because ruby 2.1! 
Generational mark and sweep garbage collector 
http://tmm1.net/ruby21-rgengc/ 
String#freeze - reuse String objects 
Less objects == less memory == less GC time 
Object allocation tracing 
http://tmm1.net/ruby21-objspace/ 
https://github.com/srawlins/allocation_stats 
Required keyword arguments 
def returns method name 
Exception#cause - ActiveRecord::StatementInvalid#cause -> Real error 
More...
Why upgrade? ... Because ruby 2.1! 
Useless benchmark 
bundle exec rspec spec/models/ems_refresh/refreshers 
1.9.3-p545 
70.85s user 2.23s system 96% cpu 1:15.98 total 
71.21s user 2.22s system 96% cpu 1:16.27 total
Why upgrade? ... Because ruby 2.1! 
Useless benchmark 
bundle exec rspec spec/models/ems_refresh/refreshers 
1.9.3-p545 
70.85s user 2.23s system 96% cpu 1:15.98 total 
71.21s user 2.22s system 96% cpu 1:16.27 total 
2.0.0-p576 
54.02s user 2.03s system 95% cpu 58.980 total 
49.96s user 2.14s system 94% cpu 54.923 total
Why upgrade? ... Because ruby 2.1! 
Useless benchmark 
bundle exec rspec spec/models/ems_refresh/refreshers 
1.9.3-p545 
70.85s user 2.23s system 96% cpu 1:15.98 total 
71.21s user 2.22s system 96% cpu 1:16.27 total 
2.0.0-p576 
54.02s user 2.03s system 95% cpu 58.980 total 
49.96s user 2.14s system 94% cpu 54.923 total 
2.1.3 
36.52s user 2.79s system 91% cpu 42.930 total 
35.68s user 2.22s system 92% cpu 40.768 total
Why upgrade? ... Because ruby 2.1! 
Example allocation information: 
Line number 
Number of allocations by object type 
Such as: 
Running: ./spec/controllers/application_controller/buttons_spec.rb:91 
223730 Arrays @ .../activerecord/lib/active_record/result.rb:35 
203280 Strings @ .../activerecord/lib/active_record/relation.rb:27
Why upgrade? ... Because ruby 2.1! 
Example allocation information: 
Line number 
Number of allocations by object type 
Such as: 
Running: ./spec/controllers/application_controller/buttons_spec.rb:91 
223730 Arrays @ .../activerecord/lib/active_record/result.rb:35 
203280 Strings @ .../activerecord/lib/active_record/relation.rb:27 
See Issue 241 and 762
But that's 2.1, let's get to 2.0 first...
Ruby 2.0 features
Faster Rails startup 
Optimizations were made to speed up 'require'
Faster Rails startup 
Optimizations were made to speed up 'require' 
(master) (1.9.3-p545) + time bundle exec rake environment 
bundle exec rake environment 3.51s user 0.63s system 99% cpu 4.148 total 
(master) (2.0.0-p576) + time bundle exec rake environment 
bundle exec rake environment 2.60s user 0.53s system 99% cpu 3.132 total
Faster Rails startup 
Optimizations were made to speed up 'require' 
(master) (1.9.3-p545) + time bundle exec rake environment 
bundle exec rake environment 3.51s user 0.63s system 99% cpu 4.148 total 
(master) (2.0.0-p576) + time bundle exec rake environment 
bundle exec rake environment 2.60s user 0.53s system 99% cpu 3.132 total 
25% faster loading of rails environment!
Faster Rails startup 
Optimizations were made to speed up 'require' 
(master) (1.9.3-p545) + time bundle exec rake environment 
bundle exec rake environment 3.51s user 0.63s system 99% cpu 4.148 total 
(master) (2.0.0-p576) + time bundle exec rake environment 
bundle exec rake environment 2.60s user 0.53s system 99% cpu 3.132 total 
25% faster loading of rails environment! 
Most obvious when: 
Running tests 
Loading Rails console
Keyword arguments 
Simplifies conventions: 
Accessing option hash values 
Default hash values 
Optional / can't handle all cases
Keyword arguments 
Example: EmsVmware#vm_connect_all 
def vm_connect_all(vm, options={}) 
defaults = { :onStartup => false } 
options = defaults.merge(options) 
vm_connect_disconnect_all_connectable_devices( 
vm, 
true, 
options[:onStartup], 
options[:user_event] 
) 
end
Keyword arguments 
Example: EmsVmware#vm_connect_all 
def vm_connect_all(vm, options={}) 
defaults = { :onStartup => false } 
options = defaults.merge(options) 
vm_connect_disconnect_all_connectable_devices( 
vm, 
true, 
options[:onStartup], 
options[:user_event] 
) 
end 
With keyword arguments: 
def vm_connect_all(vm, user_event: nil, onStartup: false) 
vm_connect_disconnect_all_connectable_devices(vm, true, onStartup, user_event) 
end
Keyword arguments 
Invoking methods not changed 
Valid on 1.9.3 / 2.0.0: 
vm_connect_all(:vm_object1, :onStartup => true, :user_event => "event1") 
vm_connect_all(:vm_object2) 
vm_connect_all(:vm_object3, :user_event => "event3") 
vm_connect_all(:vm_object3, user_event: "event3")
Keyword arguments 
Shortcomings and gotchas: 
if - valid hash key / invalid keyword argument 
Required keyword arguments added in 2.1 
http://magazine.rubyist.net/?Ruby200SpecialEn-kwarg 
http://robots.thoughtbot.com/ruby-2-keyword-arguments 
http://chriszetter.com/blog/2012/11/02/keyword-arguments-in-ruby-2- 
dot-0/
Module#prepend 
Problem: We want to debug a slow method.
Module#prepend 
Problem: We want to debug a slow method. 
Wrap the method so can time it!
Module#prepend 
Using alias_method: 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
def run 
puts "Sub" 
super 
end 
def run_with 
puts "DebugIt" 
run_without 
end 
alias_method :run_without, :run 
alias_method :run, :run_with 
end
Module#prepend 
Using alias_method: 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
def run 
puts "Sub" 
super 
end 
def run_with 
puts "DebugIt" 
run_without 
end 
Sub is a class with the slow run method... 
alias_method :run_without, :run 
alias_method :run, :run_with 
end
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
def run 
puts "Sub" 
super 
end 
def run_with 
puts "DebugIt" 
run_without 
end 
Sub is a class with the slow run method... 
alias_method :run_without, :run 
alias_method :run, :run_with 
end 
irb(main):01:0> Sub.new.run 
DebugIt 
Sub 
Parent 
Module#prepend 
Using alias_method:
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
def run 
puts "Sub" 
super 
end 
def run_with 
puts "DebugIt" 
run_without 
end 
Sub is a class with the slow run method... 
alias_method :run_without, :run 
alias_method :run, :run_with 
end 
irb(main):01:0> Sub.new.run 
DebugIt 
Sub 
Parent 
YAY! But that's really dirty! 
(alias_method_chain) 
Module#prepend 
Using alias_method:
Module#prepend 
Using include: 
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
include DebugIt 
def run 
puts "Sub" 
super 
end 
end
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
include DebugIt 
def run 
puts "Sub" 
super 
end 
end 
Sub is a class with the slow run method... 
Module#prepend 
Using include:
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
include DebugIt 
def run 
puts "Sub" 
super 
end 
end 
Sub is a class with the slow run method... 
irb(main):002:0> Sub.ancestors 
=> [Sub, DebugIt, Parent, Object, Kernel, BasicObject] 
Module#prepend 
Using include:
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
include DebugIt 
def run 
puts "Sub" 
super 
end 
end 
Sub is a class with the slow run method... 
irb(main):002:0> Sub.ancestors 
=> [Sub, DebugIt, Parent, Object, Kernel, BasicObject] 
irb(main):01:0> Sub.new.run 
Sub 
DebugIt 
Parent 
Module#prepend 
Using include:
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
include DebugIt 
def run 
puts "Sub" 
super 
end 
end 
Sub is a class with the slow run method... 
irb(main):002:0> Sub.ancestors 
=> [Sub, DebugIt, Parent, Object, Kernel, BasicObject] 
irb(main):01:0> Sub.new.run 
Sub 
DebugIt 
Parent 
UGH, Sub's method comes first! 
Module#prepend 
Using include:
Module#prepend 
Using prepend: 
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
prepend DebugIt 
def run 
puts "Sub" 
super 
end 
end
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
prepend DebugIt 
def run 
puts "Sub" 
super 
end 
end 
irb(main):002:0> Sub.ancestors 
=> [DebugIt, Sub, Parent, Object, Kernel, BasicObject] 
Module#prepend 
Using prepend:
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
prepend DebugIt 
def run 
puts "Sub" 
super 
end 
end 
irb(main):002:0> Sub.ancestors 
=> [DebugIt, Sub, Parent, Object, Kernel, BasicObject] 
irb(main):01:0> Sub.new.run 
DebugIt 
Sub 
Parent 
Module#prepend 
Using prepend:
module DebugIt 
def run 
puts "DebugIt" 
super 
end 
end 
class Parent 
def run 
puts "Parent" 
end 
end 
class Sub < Parent 
prepend DebugIt 
def run 
puts "Sub" 
super 
end 
end 
irb(main):002:0> Sub.ancestors 
=> [DebugIt, Sub, Parent, Object, Kernel, BasicObject] 
irb(main):01:0> Sub.new.run 
DebugIt 
Sub 
Parent 
Ship it! 
... but don't forget to call super! 
Module#prepend 
Using prepend:
Array of symbols: %i and %I
Array of symbols: %i and %I 
irb(main):001:0> %i{vmware redhat microsoft} 
=> [:vmware, :redhat, :microsoft]
Array of symbols: %i and %I 
irb(main):001:0> %i{vmware redhat microsoft} 
=> [:vmware, :redhat, :microsoft] 
%I allows interpolation:
Array of symbols: %i and %I 
irb(main):001:0> %i{vmware redhat microsoft} 
=> [:vmware, :redhat, :microsoft] 
%I allows interpolation: 
irb(main):002:0> prefix = "vm_" 
=> "vm_" 
irb(main):003:0> %I{#{prefix}vmware #{prefix}redhat #{prefix}microsoft} 
=> [:vm_vmware, :vm_redhat, :vm_microsoft]
Refinements 
Goal: localize monkey patches 
I'm not going to explain them because: 
Ruby's open classes 
Many gotchas... 
See Charles Nutter (@headius/jruby guy) explanation: 
http://blog.headius.com/2012/11/refining-ruby.html
Enumerable#lazy 
Enumerable methods evaluate left to right 
With lazy, chains of enumerations are evaluated right to left
Enumerable#lazy 
Enumerable methods evaluate left to right 
With lazy, chains of enumerations are evaluated right to left 
Ruby may "cheat": 
May skip creating intermediate objects 
Large collection operations may be optimized
Enumerable#lazy 
Example benchmark 
(0...1000).select(&:odd?).take(5).to_a 
(0...1000).lazy.select(&:odd?).take(5).to_a 
What is this doing?
Enumerable#lazy 
Example benchmark 
(0...1000).select(&:odd?).take(5).to_a 
(0...1000).lazy.select(&:odd?).take(5).to_a 
What is this doing? 
First 5 odd numbers 
=> [1, 3, 5, 7, 9]
Enumerable#lazy 
require 'benchmark/ips' 
Benchmark.ips do |x| 
x.report("normal") { (0...1000).select(&:odd?).take(5).to_a } 
x.report("lazy") { (0...1000).lazy.select(&:odd?).take(5).to_a } 
end
Enumerable#lazy 
require 'benchmark/ips' 
Benchmark.ips do |x| 
x.report("normal") { (0...1000).select(&:odd?).take(5).to_a } 
x.report("lazy") { (0...1000).lazy.select(&:odd?).take(5).to_a } 
end 
Calculating ------------------------------------- 
normal 1539 i/100ms 
lazy 5778 i/100ms 
------------------------------------------------- 
normal 15123.2 (±2.5%) i/s - 76950 in 5.091373s 
lazy 59797.4 (±4.0%) i/s - 300456 in 5.033123s 
See http://patshaughnessy.net/2013/4/3/ruby-2-0-works-hard-so-you-can-be- 
lazy
__dir__ 
__dir__ path of the script without the filename 
# cat test.rb 
puts __dir__ 
# ruby test.rb 
/Users/joerafaniello/Code/test
__dir__ 
__dir__ path of the script without the filename 
# cat test.rb 
puts __dir__ 
# ruby test.rb 
/Users/joerafaniello/Code/test 
We have 984 instances of File.dirname(__FILE__)! 
WAT...Why?
Ruby 2.0 breaking changes and deprecations 
Note: We're green on travis, so we're getting close...
Objects don't respond_to? to protected methods 
Ruby 1.9.3: 
respond_to?(symbol) => public and protected methods 
respond_to?(symbol, true) => all methods
Objects don't respond_to? to protected methods 
Ruby 1.9.3: 
respond_to?(symbol) => public and protected methods 
respond_to?(symbol, true) => all methods 
Ruby 2.0.0 
respond_to?(symbol) => public methods only 
respond_to?(symbol, true) => all methods
Objects don't respond_to? to protected methods 
class Worker 
protected 
def run 
end 
end
Objects don't respond_to? to protected methods 
class Worker 
protected 
def run 
end 
end 
Worker.new.respond_to?(:run) 
1.9.3 => true 
2.0.0 => false
Objects don't respond_to? to protected methods 
class Worker 
protected 
def run 
end 
end 
Worker.new.respond_to?(:run) 
1.9.3 => true 
2.0.0 => false 
Pass true as second argument... 
Worker.new.respond_to?(:run, true) 
1.9.3 => true 
2.0.0 => true
Objects don't respond_to? to protected methods 
class Worker 
protected 
def run 
end 
end 
Worker.new.respond_to?(:run) 
1.9.3 => true 
2.0.0 => false 
Pass true as second argument... 
Worker.new.respond_to?(:run, true) 
1.9.3 => true 
2.0.0 => true 
See Pull #685 - default_value_for gem
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256"
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256" 
Ruby 1.9.3 
US-ASCII is the default encoding of ruby scripts
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256" 
Ruby 1.9.3 
US-ASCII is the default encoding of ruby scripts 
Binary string literals become ASCII-8BIT:
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256" 
Ruby 1.9.3 
US-ASCII is the default encoding of ruby scripts 
Binary string literals become ASCII-8BIT: 
irb(main):001:0> require './test' 
=> true 
irb(main):002:0> FOO.encoding 
=> #<Encoding:ASCII-8BIT>
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256"
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256" 
Ruby 2.0.0 
UTF-8 is the default encoding
UTF-8 is the default character encoding of ruby 
scripts 
# cat test.rb 
FOO = "222dL256" 
Ruby 2.0.0 
UTF-8 is the default encoding 
Binary string literals become UTF-8 even if invalid: 
irb(main):001:0> require './test' 
=> true 
irb(main):002:0> FOO.encoding 
=> #<Encoding:UTF-8> 
irb(main):003:0> FOO.valid_encoding? 
=> false
UTF-8 is the default character encoding of ruby 
scripts 
So, what's the problem? 
Binary strings are used in many places for vm "fleecing" 
Invalid UTF-8 encoded strings != raw binary:
UTF-8 is the default character encoding of ruby 
scripts 
So, what's the problem? 
Binary strings are used in many places for vm "fleecing" 
Invalid UTF-8 encoded strings != raw binary: 
irb(main):003:0> FOO.valid_encoding? 
=> false 
irb(main):004:0> FOO == "222dL256".force_encoding("ASCII-8BIT") 
=> false
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Force binary on individual Strings: 
1.9.3/2.0.0 compatible 
Painful on files with many binary string literals
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Force binary on individual Strings: 
1.9.3/2.0.0 compatible 
Painful on files with many binary string literals 
# cat test.rb 
FOO = "222dL256".force_encoding("ASCII-8BIT")
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Force binary on individual Strings: 
1.9.3/2.0.0 compatible 
Painful on files with many binary string literals 
# cat test.rb 
FOO = "222dL256".force_encoding("ASCII-8BIT") 
irb(main):001:0> require './test' 
=> true 
irb(main):002:0> FOO.encoding 
=> #<Encoding:ASCII-8BIT> 
irb(main):003:0> FOO.valid_encoding? 
=> true 
irb(main):004:0> FOO == "222dL256".force_encoding("ASCII-8BIT") 
=> true
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Use String#b on individual strings 
Not compatible with ruby 1.9.3 
Copies the String in ASCII-8BIT encoding 
Note: String#force_encoding("ASCII-8BIT") modifies the receiver
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Add #encoding magic comment at top 
1.9.3/2.0.0 compatible 
Good option when binary strings are expected
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Add #encoding magic comment at top 
1.9.3/2.0.0 compatible 
Good option when binary strings are expected 
# cat test.rb 
# encoding: US-ASCII 
FOO = "222dL256"
UTF-8 is the default character encoding of ruby 
scripts 
Solutions: 
Add #encoding magic comment at top 
1.9.3/2.0.0 compatible 
Good option when binary strings are expected 
# cat test.rb 
# encoding: US-ASCII 
FOO = "222dL256" 
irb(main):001:0> require './test' 
=> true 
irb(main):002:0> FOO.encoding 
=> #<Encoding:ASCII-8BIT>
Descriptors except 0, 1, 2 are closed in child 
processes 
Prevents file descriptor leakage 
See Pull #682, Issue #459, and https://bugs.ruby-lang.org/issues/5041
Descriptors except 0, 1, 2 are closed in child 
processes 
Prevents file descriptor leakage 
See Pull #682, Issue #459, and https://bugs.ruby-lang.org/issues/5041 
Example: shared pipe to communicate data between two processes
Descriptors except 0, 1, 2 are closed in child 
processes 
Prevents file descriptor leakage 
See Pull #682, Issue #459, and https://bugs.ruby-lang.org/issues/5041 
Example: shared pipe to communicate data between two processes 
Use IO#close_on_exec = false 
reader, writer = IO.pipe 
writerfd = writer.fileno 
my_env["WRITER_FD"] = writerfd.to_s 
+ 
+ writer.close_on_exec = false 
+ 
pid = Kernel.spawn(my_env, "ruby #{SERVER_PATH}VixDiskLibServer.rb", 
[:out, :err] => [LOG_FILE, "a"], 
:unsetenv_others => true,
String#lines returns an array 
Also String#chars, #bytes and #codepoints 
Previously, returned enumerators 
Above are deprecated for StringIO, IO and friends
String#lines returns an array 
Also String#chars, #bytes and #codepoints 
Previously, returned enumerators 
Above are deprecated for StringIO, IO and friends 
StringIO#lines deprecated, so use #each_line instead: 
@log_stream.rewind 
- lines = @log_stream.lines.to_a 
+ lines = @log_stream.each_line.to_a 
lines.length.should == 1 
line = lines.first.chomp
String#lines returns an array 
Also String#chars, #bytes and #codepoints 
Previously, returned enumerators 
Above are deprecated for StringIO, IO and friends 
StringIO#lines deprecated, so use #each_line instead: 
@log_stream.rewind 
- lines = @log_stream.lines.to_a 
+ lines = @log_stream.each_line.to_a 
lines.length.should == 1 
line = lines.first.chomp 
See Pull #714
Ok, great, but are we there yet???
"Fall cleanup" of old code 
"...Now I've only been an OpenBSD developer for 11 years, one year less than 
this header has existed, but in that brief time, I've learned a thing or two 
about deleting obsolete code. It doesn't delete itself. And worse, people 
will continue using it until you force them onto a better path." 
http://freshbsd.org/commit/openbsd/68dc781944a2c5b90f8b6e1069a4201750c67f94
"Fall cleanup" of old code 
"...Now I've only been an OpenBSD developer for 11 years, one year less than 
this header has existed, but in that brief time, I've learned a thing or two 
about deleting obsolete code. It doesn't delete itself. And worse, people 
will continue using it until you force them onto a better path." 
http://freshbsd.org/commit/openbsd/68dc781944a2c5b90f8b6e1069a4201750c67f94 
Git is our friend if we really want it back
"Fall cleanup" of old code 
Path to ruby 2.0...
"Fall cleanup" of old code 
Path to ruby 2.0... 
83 commits 
565 lines added 
5,553 lines deleted
"Fall cleanup" of old code 
Path to ruby 2.0... 
83 commits 
565 lines added 
5,553 lines deleted 
A good start?
"Fall cleanup" of old code 
More "opportunities" 
host directory 
soap4r/actionwebservice (fork) 
handsoap (fork) - note, useful but still forked :-( 
ruport (fork) 
ziya (fork) - patches rails! 
prototype 
old rails plugins 
old gems 
old monkey patches
Slow tests 
Tests take 30+ minutes on CI servers 
Separate tests 
Minimizing setup (database inserts) 
Remove invalid/not useful/duplicate tests 
Allocation tracing with ruby 2.1 
Cut support for 1.9.3 when 2.0 is stable
Building 2.0 appliances 
Verified Ruby 2.0 on CentOS appliance: 
Appliance startup 
SmartState Analysis "fleecing" using vddk 
vCenter inventory 
Basic reporting
Building 2.0 appliances 
Goal: automate building ruby 2.0 appliances 
We currently use ruby 1.9.3 through SCL rpms 
Not multi-platform 
Restricts updating of some gems 
Ruby 2.1 is not yet packaged as SCL rpms
Building 2.0 appliances 
Solution: 
rpms for base CentOS OS 
rpms needed to build ruby and compiled gems 
libxml2-devel, libxslt-devel, etc.
Building 2.0 appliances 
Solution: 
rpms for base CentOS OS 
rpms needed to build ruby and compiled gems 
libxml2-devel, libxslt-devel, etc. 
Use ruby-install or ruby-build for building ruby 
https://github.com/postmodern/ruby-install 
https://github.com/sstephenson/ruby-build
Building 2.0 appliances 
Solution: 
rpms for base CentOS OS 
rpms needed to build ruby and compiled gems 
libxml2-devel, libxslt-devel, etc. 
Use ruby-install or ruby-build for building ruby 
https://github.com/postmodern/ruby-install 
https://github.com/sstephenson/ruby-build 
Let bundler handle what it does well...
Developer setup 
2.0.0 is not much different from 1.9.3: 
Install using rvm, ruby-install, or ruby-build 
Manage with rvm, rbenv, or chruby 
Need guinea pigs to try it and document any issues 
Others tools, such as rubymine, may require some configuration
Links 
2.0 open issues: https://github.com/ManageIQ/manageiq/labels/ruby%202 
2.0 closed issues: https://github.com/ManageIQ/manageiq/issues? 
q=label%3A%22ruby+2%22+is%3Aclosed 
2.0 in depth: http://globaldev.co.uk/2013/03/ruby-2-0-0-in-detail/ 
2.1 in depth: http://globaldev.co.uk/2014/05/ruby-2-1-in-detail/ 
Slides available here: https://github.com/jrafanie/manageiq_summit_ruby20 
Slides written in markdown using remarkjs: http://remarkjs.com/#1
uestions?

More Related Content

What's hot

Antons Kranga Building Agile Infrastructures
Antons Kranga   Building Agile InfrastructuresAntons Kranga   Building Agile Infrastructures
Antons Kranga Building Agile Infrastructures
Antons Kranga
 
Advanced task management with Celery
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with Celery
Mahendra M
 
Introduction to Marionette Collective
Introduction to Marionette CollectiveIntroduction to Marionette Collective
Introduction to Marionette Collective
Puppet
 
Celery with python
Celery with pythonCelery with python
Celery with python
Alexandre González Rodríguez
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)
Soshi Nemoto
 
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Puppet
 
Scaling up task processing with Celery
Scaling up task processing with CeleryScaling up task processing with Celery
Scaling up task processing with Celery
Nicolas Grasset
 
Introduction to MCollective - SF PUG
Introduction to MCollective - SF PUGIntroduction to MCollective - SF PUG
Introduction to MCollective - SF PUG
Puppet
 
Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...
Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...
Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...
Puppet
 
Introduction to orchestration using Mcollective
Introduction to orchestration using McollectiveIntroduction to orchestration using Mcollective
Introduction to orchestration using Mcollective
Puppet
 
The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)
Olaf Alders
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
Graham Dumpleton
 
Pro Puppet
Pro PuppetPro Puppet
Pro Puppet
dsadas
 
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Puppet
 
Performance Tuning Your Puppet Infrastructure - PuppetConf 2014
Performance Tuning Your Puppet Infrastructure - PuppetConf 2014Performance Tuning Your Puppet Infrastructure - PuppetConf 2014
Performance Tuning Your Puppet Infrastructure - PuppetConf 2014
Puppet
 
The Puppet Master on the JVM - PuppetConf 2014
The Puppet Master on the JVM - PuppetConf 2014The Puppet Master on the JVM - PuppetConf 2014
The Puppet Master on the JVM - PuppetConf 2014
Puppet
 
Celery
CeleryCelery
Celery
Fatih Erikli
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
Graham Dumpleton
 
Scaling Django with gevent
Scaling Django with geventScaling Django with gevent
Scaling Django with gevent
Mahendra M
 
Django deployment best practices
Django deployment best practicesDjango deployment best practices
Django deployment best practices
Erik LaBianca
 

What's hot (20)

Antons Kranga Building Agile Infrastructures
Antons Kranga   Building Agile InfrastructuresAntons Kranga   Building Agile Infrastructures
Antons Kranga Building Agile Infrastructures
 
Advanced task management with Celery
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with Celery
 
Introduction to Marionette Collective
Introduction to Marionette CollectiveIntroduction to Marionette Collective
Introduction to Marionette Collective
 
Celery with python
Celery with pythonCelery with python
Celery with python
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)
 
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
 
Scaling up task processing with Celery
Scaling up task processing with CeleryScaling up task processing with Celery
Scaling up task processing with Celery
 
Introduction to MCollective - SF PUG
Introduction to MCollective - SF PUGIntroduction to MCollective - SF PUG
Introduction to MCollective - SF PUG
 
Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...
Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...
Building and Testing from Scratch a Puppet Environment with Docker - PuppetCo...
 
Introduction to orchestration using Mcollective
Introduction to orchestration using McollectiveIntroduction to orchestration using Mcollective
Introduction to orchestration using Mcollective
 
The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
 
Pro Puppet
Pro PuppetPro Puppet
Pro Puppet
 
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
 
Performance Tuning Your Puppet Infrastructure - PuppetConf 2014
Performance Tuning Your Puppet Infrastructure - PuppetConf 2014Performance Tuning Your Puppet Infrastructure - PuppetConf 2014
Performance Tuning Your Puppet Infrastructure - PuppetConf 2014
 
The Puppet Master on the JVM - PuppetConf 2014
The Puppet Master on the JVM - PuppetConf 2014The Puppet Master on the JVM - PuppetConf 2014
The Puppet Master on the JVM - PuppetConf 2014
 
Celery
CeleryCelery
Celery
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
 
Scaling Django with gevent
Scaling Django with geventScaling Django with gevent
Scaling Django with gevent
 
Django deployment best practices
Django deployment best practicesDjango deployment best practices
Django deployment best practices
 

Similar to Design Summit - Migrating to Ruby 2 - Joe Rafaniello

Speedy TDD with Rails
Speedy TDD with RailsSpeedy TDD with Rails
Speedy TDD with Rails
PatchSpace Ltd
 
How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...
How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...
How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...
Puppet
 
Puppet quick start guide
Puppet quick start guidePuppet quick start guide
Puppet quick start guide
Suhan Dharmasuriya
 
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Fabrice Bernhard
 
Strategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoringStrategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoring
Alessandro Franceschi
 
Lessons Learnt in 2009
Lessons Learnt in 2009Lessons Learnt in 2009
Lessons Learnt in 2009
pratiknaik
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
Papp Laszlo
 
DevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven InfrastructureDevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven Infrastructure
Antons Kranga
 
把鐵路開進視窗裡
把鐵路開進視窗裡把鐵路開進視窗裡
把鐵路開進視窗裡
Wei Jen Lu
 
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Carlos Sanchez
 
Ruby and Rails Packaging to Production
Ruby and Rails Packaging to ProductionRuby and Rails Packaging to Production
Ruby and Rails Packaging to Production
Fabio Kung
 
Writing & Sharing Great Modules on the Puppet Forge
Writing & Sharing Great Modules on the Puppet ForgeWriting & Sharing Great Modules on the Puppet Forge
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
Rabble .
 
Moo at System::Image::Update
Moo at System::Image::UpdateMoo at System::Image::Update
Moo at System::Image::Update
Jens Rehsack
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
miguel dominguez
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
MortazaJohari
 
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
 
Writing & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonWriting & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp Boston
Puppet
 
JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...
JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...
JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...
GeeksLab Odessa
 
Puppet At Twitter - Puppet Camp Silicon Valley
Puppet At Twitter - Puppet Camp Silicon ValleyPuppet At Twitter - Puppet Camp Silicon Valley
Puppet At Twitter - Puppet Camp Silicon Valley
Puppet
 

Similar to Design Summit - Migrating to Ruby 2 - Joe Rafaniello (20)

Speedy TDD with Rails
Speedy TDD with RailsSpeedy TDD with Rails
Speedy TDD with Rails
 
How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...
How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...
How Puppet Enables the Use of Lightweight Virtualized Containers - PuppetConf...
 
Puppet quick start guide
Puppet quick start guidePuppet quick start guide
Puppet quick start guide
 
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
 
Strategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoringStrategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoring
 
Lessons Learnt in 2009
Lessons Learnt in 2009Lessons Learnt in 2009
Lessons Learnt in 2009
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
DevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven InfrastructureDevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven Infrastructure
 
把鐵路開進視窗裡
把鐵路開進視窗裡把鐵路開進視窗裡
把鐵路開進視窗裡
 
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
 
Ruby and Rails Packaging to Production
Ruby and Rails Packaging to ProductionRuby and Rails Packaging to Production
Ruby and Rails Packaging to Production
 
Writing & Sharing Great Modules on the Puppet Forge
Writing & Sharing Great Modules on the Puppet ForgeWriting & Sharing Great Modules on the Puppet Forge
Writing & Sharing Great Modules on the Puppet Forge
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Moo at System::Image::Update
Moo at System::Image::UpdateMoo at System::Image::Update
Moo at System::Image::Update
 
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,...
 
Writing & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonWriting & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp Boston
 
JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...
JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...
JS Lab2017_Андрей Кучеренко _Разработка мультипакетных приложения: причины, с...
 
Puppet At Twitter - Puppet Camp Silicon Valley
Puppet At Twitter - Puppet Camp Silicon ValleyPuppet At Twitter - Puppet Camp Silicon Valley
Puppet At Twitter - Puppet Camp Silicon Valley
 

More from ManageIQ

ManageIQ - Sprint 237 Review - Slide Deck
ManageIQ - Sprint 237 Review - Slide DeckManageIQ - Sprint 237 Review - Slide Deck
ManageIQ - Sprint 237 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 235 Review - Slide Deck
ManageIQ - Sprint 235 Review - Slide DeckManageIQ - Sprint 235 Review - Slide Deck
ManageIQ - Sprint 235 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 234 Review - Slide Deck
ManageIQ - Sprint 234 Review - Slide DeckManageIQ - Sprint 234 Review - Slide Deck
ManageIQ - Sprint 234 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 233 Review - Slide Deck
ManageIQ - Sprint 233 Review - Slide DeckManageIQ - Sprint 233 Review - Slide Deck
ManageIQ - Sprint 233 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 232 Review - Slide Deck
ManageIQ - Sprint 232 Review - Slide DeckManageIQ - Sprint 232 Review - Slide Deck
ManageIQ - Sprint 232 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 231 Review - Slide Deck
ManageIQ - Sprint 231 Review - Slide DeckManageIQ - Sprint 231 Review - Slide Deck
ManageIQ - Sprint 231 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 230 Review - Slide Deck
ManageIQ - Sprint 230 Review - Slide DeckManageIQ - Sprint 230 Review - Slide Deck
ManageIQ - Sprint 230 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 229 Review - Slide Deck
ManageIQ - Sprint 229 Review - Slide DeckManageIQ - Sprint 229 Review - Slide Deck
ManageIQ - Sprint 229 Review - Slide Deck
ManageIQ
 
ManageIQ - Sprint 228 Review - Slide Deck
ManageIQ - Sprint 228 Review - Slide DeckManageIQ - Sprint 228 Review - Slide Deck
ManageIQ - Sprint 228 Review - Slide Deck
ManageIQ
 
Sprint 227
Sprint 227Sprint 227
Sprint 227
ManageIQ
 
Sprint 226
Sprint 226Sprint 226
Sprint 226
ManageIQ
 
Sprint 225
Sprint 225Sprint 225
Sprint 225
ManageIQ
 
Sprint 224
Sprint 224Sprint 224
Sprint 224
ManageIQ
 
Sprint 223
Sprint 223Sprint 223
Sprint 223
ManageIQ
 
Sprint 222
Sprint 222Sprint 222
Sprint 222
ManageIQ
 
Sprint 221
Sprint 221Sprint 221
Sprint 221
ManageIQ
 
Sprint 220
Sprint 220Sprint 220
Sprint 220
ManageIQ
 
Sprint 219
Sprint 219Sprint 219
Sprint 219
ManageIQ
 
Sprint 218
Sprint 218Sprint 218
Sprint 218
ManageIQ
 

More from ManageIQ (20)

ManageIQ - Sprint 237 Review - Slide Deck
ManageIQ - Sprint 237 Review - Slide DeckManageIQ - Sprint 237 Review - Slide Deck
ManageIQ - Sprint 237 Review - Slide Deck
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
ManageIQ - Sprint 235 Review - Slide Deck
ManageIQ - Sprint 235 Review - Slide DeckManageIQ - Sprint 235 Review - Slide Deck
ManageIQ - Sprint 235 Review - Slide Deck
 
ManageIQ - Sprint 234 Review - Slide Deck
ManageIQ - Sprint 234 Review - Slide DeckManageIQ - Sprint 234 Review - Slide Deck
ManageIQ - Sprint 234 Review - Slide Deck
 
ManageIQ - Sprint 233 Review - Slide Deck
ManageIQ - Sprint 233 Review - Slide DeckManageIQ - Sprint 233 Review - Slide Deck
ManageIQ - Sprint 233 Review - Slide Deck
 
ManageIQ - Sprint 232 Review - Slide Deck
ManageIQ - Sprint 232 Review - Slide DeckManageIQ - Sprint 232 Review - Slide Deck
ManageIQ - Sprint 232 Review - Slide Deck
 
ManageIQ - Sprint 231 Review - Slide Deck
ManageIQ - Sprint 231 Review - Slide DeckManageIQ - Sprint 231 Review - Slide Deck
ManageIQ - Sprint 231 Review - Slide Deck
 
ManageIQ - Sprint 230 Review - Slide Deck
ManageIQ - Sprint 230 Review - Slide DeckManageIQ - Sprint 230 Review - Slide Deck
ManageIQ - Sprint 230 Review - Slide Deck
 
ManageIQ - Sprint 229 Review - Slide Deck
ManageIQ - Sprint 229 Review - Slide DeckManageIQ - Sprint 229 Review - Slide Deck
ManageIQ - Sprint 229 Review - Slide Deck
 
ManageIQ - Sprint 228 Review - Slide Deck
ManageIQ - Sprint 228 Review - Slide DeckManageIQ - Sprint 228 Review - Slide Deck
ManageIQ - Sprint 228 Review - Slide Deck
 
Sprint 227
Sprint 227Sprint 227
Sprint 227
 
Sprint 226
Sprint 226Sprint 226
Sprint 226
 
Sprint 225
Sprint 225Sprint 225
Sprint 225
 
Sprint 224
Sprint 224Sprint 224
Sprint 224
 
Sprint 223
Sprint 223Sprint 223
Sprint 223
 
Sprint 222
Sprint 222Sprint 222
Sprint 222
 
Sprint 221
Sprint 221Sprint 221
Sprint 221
 
Sprint 220
Sprint 220Sprint 220
Sprint 220
 
Sprint 219
Sprint 219Sprint 219
Sprint 219
 
Sprint 218
Sprint 218Sprint 218
Sprint 218
 

Recently uploaded

Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
HarisZaheer8
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
Pravash Chandra Das
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
GDSC PJATK
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
fredae14
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
saastr
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 

Recently uploaded (20)

Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 

Design Summit - Migrating to Ruby 2 - Joe Rafaniello

  • 1. Upgrading to Ruby 2.x Joe Rafaniello @jrafanie
  • 3. 13
  • 4. Agenda 1. History 2. Why upgrade? 3. Ruby 2.1 4. Ruby 2.0 5. "Fall cleanup" of old code 6. Slow tests 7. Building 2.0 appliances 8. Developer setup 9. Links 10. Questions?
  • 5. History Tue Nov 1 2011: First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ
  • 6. History Tue Nov 1 2011: First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ Tue Apr 23 2013: Ruby 1.9.3 finally...
  • 7. History Tue Nov 1 2011: First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ Tue Apr 23 2013: Ruby 1.9.3 finally... 540 days???
  • 8. History Tue Nov 1 2011: First ruby 1.8.7 -> 1.9.3 related commit on ManageIQ Tue Apr 23 2013: Ruby 1.9.3 finally... 540 days??? Lesson learned: Don't wait to upgrade!
  • 10. Why upgrade? We're behind!!! Ruby 1.9.3 is ending In maintenance until February 23, 2014 Security only mode until February 23, 2015 Ruby 2.0.0 is nearly 20 months old Ruby 2.1.0 is nearly 10 months old Ruby 2.2.0 is scheduled for a Christmas release
  • 11. Why upgrade? ... Because ruby 2.1! Generational mark and sweep garbage collector http://tmm1.net/ruby21-rgengc/ String#freeze - reuse String objects Less objects == less memory == less GC time Object allocation tracing http://tmm1.net/ruby21-objspace/ https://github.com/srawlins/allocation_stats Required keyword arguments def returns method name Exception#cause - ActiveRecord::StatementInvalid#cause -> Real error More...
  • 12. Why upgrade? ... Because ruby 2.1! Useless benchmark bundle exec rspec spec/models/ems_refresh/refreshers 1.9.3-p545 70.85s user 2.23s system 96% cpu 1:15.98 total 71.21s user 2.22s system 96% cpu 1:16.27 total
  • 13. Why upgrade? ... Because ruby 2.1! Useless benchmark bundle exec rspec spec/models/ems_refresh/refreshers 1.9.3-p545 70.85s user 2.23s system 96% cpu 1:15.98 total 71.21s user 2.22s system 96% cpu 1:16.27 total 2.0.0-p576 54.02s user 2.03s system 95% cpu 58.980 total 49.96s user 2.14s system 94% cpu 54.923 total
  • 14. Why upgrade? ... Because ruby 2.1! Useless benchmark bundle exec rspec spec/models/ems_refresh/refreshers 1.9.3-p545 70.85s user 2.23s system 96% cpu 1:15.98 total 71.21s user 2.22s system 96% cpu 1:16.27 total 2.0.0-p576 54.02s user 2.03s system 95% cpu 58.980 total 49.96s user 2.14s system 94% cpu 54.923 total 2.1.3 36.52s user 2.79s system 91% cpu 42.930 total 35.68s user 2.22s system 92% cpu 40.768 total
  • 15. Why upgrade? ... Because ruby 2.1! Example allocation information: Line number Number of allocations by object type Such as: Running: ./spec/controllers/application_controller/buttons_spec.rb:91 223730 Arrays @ .../activerecord/lib/active_record/result.rb:35 203280 Strings @ .../activerecord/lib/active_record/relation.rb:27
  • 16. Why upgrade? ... Because ruby 2.1! Example allocation information: Line number Number of allocations by object type Such as: Running: ./spec/controllers/application_controller/buttons_spec.rb:91 223730 Arrays @ .../activerecord/lib/active_record/result.rb:35 203280 Strings @ .../activerecord/lib/active_record/relation.rb:27 See Issue 241 and 762
  • 17. But that's 2.1, let's get to 2.0 first...
  • 19. Faster Rails startup Optimizations were made to speed up 'require'
  • 20. Faster Rails startup Optimizations were made to speed up 'require' (master) (1.9.3-p545) + time bundle exec rake environment bundle exec rake environment 3.51s user 0.63s system 99% cpu 4.148 total (master) (2.0.0-p576) + time bundle exec rake environment bundle exec rake environment 2.60s user 0.53s system 99% cpu 3.132 total
  • 21. Faster Rails startup Optimizations were made to speed up 'require' (master) (1.9.3-p545) + time bundle exec rake environment bundle exec rake environment 3.51s user 0.63s system 99% cpu 4.148 total (master) (2.0.0-p576) + time bundle exec rake environment bundle exec rake environment 2.60s user 0.53s system 99% cpu 3.132 total 25% faster loading of rails environment!
  • 22. Faster Rails startup Optimizations were made to speed up 'require' (master) (1.9.3-p545) + time bundle exec rake environment bundle exec rake environment 3.51s user 0.63s system 99% cpu 4.148 total (master) (2.0.0-p576) + time bundle exec rake environment bundle exec rake environment 2.60s user 0.53s system 99% cpu 3.132 total 25% faster loading of rails environment! Most obvious when: Running tests Loading Rails console
  • 23. Keyword arguments Simplifies conventions: Accessing option hash values Default hash values Optional / can't handle all cases
  • 24. Keyword arguments Example: EmsVmware#vm_connect_all def vm_connect_all(vm, options={}) defaults = { :onStartup => false } options = defaults.merge(options) vm_connect_disconnect_all_connectable_devices( vm, true, options[:onStartup], options[:user_event] ) end
  • 25. Keyword arguments Example: EmsVmware#vm_connect_all def vm_connect_all(vm, options={}) defaults = { :onStartup => false } options = defaults.merge(options) vm_connect_disconnect_all_connectable_devices( vm, true, options[:onStartup], options[:user_event] ) end With keyword arguments: def vm_connect_all(vm, user_event: nil, onStartup: false) vm_connect_disconnect_all_connectable_devices(vm, true, onStartup, user_event) end
  • 26. Keyword arguments Invoking methods not changed Valid on 1.9.3 / 2.0.0: vm_connect_all(:vm_object1, :onStartup => true, :user_event => "event1") vm_connect_all(:vm_object2) vm_connect_all(:vm_object3, :user_event => "event3") vm_connect_all(:vm_object3, user_event: "event3")
  • 27. Keyword arguments Shortcomings and gotchas: if - valid hash key / invalid keyword argument Required keyword arguments added in 2.1 http://magazine.rubyist.net/?Ruby200SpecialEn-kwarg http://robots.thoughtbot.com/ruby-2-keyword-arguments http://chriszetter.com/blog/2012/11/02/keyword-arguments-in-ruby-2- dot-0/
  • 28. Module#prepend Problem: We want to debug a slow method.
  • 29. Module#prepend Problem: We want to debug a slow method. Wrap the method so can time it!
  • 30. Module#prepend Using alias_method: class Parent def run puts "Parent" end end class Sub < Parent def run puts "Sub" super end def run_with puts "DebugIt" run_without end alias_method :run_without, :run alias_method :run, :run_with end
  • 31. Module#prepend Using alias_method: class Parent def run puts "Parent" end end class Sub < Parent def run puts "Sub" super end def run_with puts "DebugIt" run_without end Sub is a class with the slow run method... alias_method :run_without, :run alias_method :run, :run_with end
  • 32. class Parent def run puts "Parent" end end class Sub < Parent def run puts "Sub" super end def run_with puts "DebugIt" run_without end Sub is a class with the slow run method... alias_method :run_without, :run alias_method :run, :run_with end irb(main):01:0> Sub.new.run DebugIt Sub Parent Module#prepend Using alias_method:
  • 33. class Parent def run puts "Parent" end end class Sub < Parent def run puts "Sub" super end def run_with puts "DebugIt" run_without end Sub is a class with the slow run method... alias_method :run_without, :run alias_method :run, :run_with end irb(main):01:0> Sub.new.run DebugIt Sub Parent YAY! But that's really dirty! (alias_method_chain) Module#prepend Using alias_method:
  • 34. Module#prepend Using include: module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent include DebugIt def run puts "Sub" super end end
  • 35. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent include DebugIt def run puts "Sub" super end end Sub is a class with the slow run method... Module#prepend Using include:
  • 36. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent include DebugIt def run puts "Sub" super end end Sub is a class with the slow run method... irb(main):002:0> Sub.ancestors => [Sub, DebugIt, Parent, Object, Kernel, BasicObject] Module#prepend Using include:
  • 37. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent include DebugIt def run puts "Sub" super end end Sub is a class with the slow run method... irb(main):002:0> Sub.ancestors => [Sub, DebugIt, Parent, Object, Kernel, BasicObject] irb(main):01:0> Sub.new.run Sub DebugIt Parent Module#prepend Using include:
  • 38. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent include DebugIt def run puts "Sub" super end end Sub is a class with the slow run method... irb(main):002:0> Sub.ancestors => [Sub, DebugIt, Parent, Object, Kernel, BasicObject] irb(main):01:0> Sub.new.run Sub DebugIt Parent UGH, Sub's method comes first! Module#prepend Using include:
  • 39. Module#prepend Using prepend: module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent prepend DebugIt def run puts "Sub" super end end
  • 40. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent prepend DebugIt def run puts "Sub" super end end irb(main):002:0> Sub.ancestors => [DebugIt, Sub, Parent, Object, Kernel, BasicObject] Module#prepend Using prepend:
  • 41. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent prepend DebugIt def run puts "Sub" super end end irb(main):002:0> Sub.ancestors => [DebugIt, Sub, Parent, Object, Kernel, BasicObject] irb(main):01:0> Sub.new.run DebugIt Sub Parent Module#prepend Using prepend:
  • 42. module DebugIt def run puts "DebugIt" super end end class Parent def run puts "Parent" end end class Sub < Parent prepend DebugIt def run puts "Sub" super end end irb(main):002:0> Sub.ancestors => [DebugIt, Sub, Parent, Object, Kernel, BasicObject] irb(main):01:0> Sub.new.run DebugIt Sub Parent Ship it! ... but don't forget to call super! Module#prepend Using prepend:
  • 43. Array of symbols: %i and %I
  • 44. Array of symbols: %i and %I irb(main):001:0> %i{vmware redhat microsoft} => [:vmware, :redhat, :microsoft]
  • 45. Array of symbols: %i and %I irb(main):001:0> %i{vmware redhat microsoft} => [:vmware, :redhat, :microsoft] %I allows interpolation:
  • 46. Array of symbols: %i and %I irb(main):001:0> %i{vmware redhat microsoft} => [:vmware, :redhat, :microsoft] %I allows interpolation: irb(main):002:0> prefix = "vm_" => "vm_" irb(main):003:0> %I{#{prefix}vmware #{prefix}redhat #{prefix}microsoft} => [:vm_vmware, :vm_redhat, :vm_microsoft]
  • 47. Refinements Goal: localize monkey patches I'm not going to explain them because: Ruby's open classes Many gotchas... See Charles Nutter (@headius/jruby guy) explanation: http://blog.headius.com/2012/11/refining-ruby.html
  • 48. Enumerable#lazy Enumerable methods evaluate left to right With lazy, chains of enumerations are evaluated right to left
  • 49. Enumerable#lazy Enumerable methods evaluate left to right With lazy, chains of enumerations are evaluated right to left Ruby may "cheat": May skip creating intermediate objects Large collection operations may be optimized
  • 50. Enumerable#lazy Example benchmark (0...1000).select(&:odd?).take(5).to_a (0...1000).lazy.select(&:odd?).take(5).to_a What is this doing?
  • 51. Enumerable#lazy Example benchmark (0...1000).select(&:odd?).take(5).to_a (0...1000).lazy.select(&:odd?).take(5).to_a What is this doing? First 5 odd numbers => [1, 3, 5, 7, 9]
  • 52. Enumerable#lazy require 'benchmark/ips' Benchmark.ips do |x| x.report("normal") { (0...1000).select(&:odd?).take(5).to_a } x.report("lazy") { (0...1000).lazy.select(&:odd?).take(5).to_a } end
  • 53. Enumerable#lazy require 'benchmark/ips' Benchmark.ips do |x| x.report("normal") { (0...1000).select(&:odd?).take(5).to_a } x.report("lazy") { (0...1000).lazy.select(&:odd?).take(5).to_a } end Calculating ------------------------------------- normal 1539 i/100ms lazy 5778 i/100ms ------------------------------------------------- normal 15123.2 (±2.5%) i/s - 76950 in 5.091373s lazy 59797.4 (±4.0%) i/s - 300456 in 5.033123s See http://patshaughnessy.net/2013/4/3/ruby-2-0-works-hard-so-you-can-be- lazy
  • 54. __dir__ __dir__ path of the script without the filename # cat test.rb puts __dir__ # ruby test.rb /Users/joerafaniello/Code/test
  • 55. __dir__ __dir__ path of the script without the filename # cat test.rb puts __dir__ # ruby test.rb /Users/joerafaniello/Code/test We have 984 instances of File.dirname(__FILE__)! WAT...Why?
  • 56. Ruby 2.0 breaking changes and deprecations Note: We're green on travis, so we're getting close...
  • 57. Objects don't respond_to? to protected methods Ruby 1.9.3: respond_to?(symbol) => public and protected methods respond_to?(symbol, true) => all methods
  • 58. Objects don't respond_to? to protected methods Ruby 1.9.3: respond_to?(symbol) => public and protected methods respond_to?(symbol, true) => all methods Ruby 2.0.0 respond_to?(symbol) => public methods only respond_to?(symbol, true) => all methods
  • 59. Objects don't respond_to? to protected methods class Worker protected def run end end
  • 60. Objects don't respond_to? to protected methods class Worker protected def run end end Worker.new.respond_to?(:run) 1.9.3 => true 2.0.0 => false
  • 61. Objects don't respond_to? to protected methods class Worker protected def run end end Worker.new.respond_to?(:run) 1.9.3 => true 2.0.0 => false Pass true as second argument... Worker.new.respond_to?(:run, true) 1.9.3 => true 2.0.0 => true
  • 62. Objects don't respond_to? to protected methods class Worker protected def run end end Worker.new.respond_to?(:run) 1.9.3 => true 2.0.0 => false Pass true as second argument... Worker.new.respond_to?(:run, true) 1.9.3 => true 2.0.0 => true See Pull #685 - default_value_for gem
  • 63. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256"
  • 64. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256" Ruby 1.9.3 US-ASCII is the default encoding of ruby scripts
  • 65. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256" Ruby 1.9.3 US-ASCII is the default encoding of ruby scripts Binary string literals become ASCII-8BIT:
  • 66. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256" Ruby 1.9.3 US-ASCII is the default encoding of ruby scripts Binary string literals become ASCII-8BIT: irb(main):001:0> require './test' => true irb(main):002:0> FOO.encoding => #<Encoding:ASCII-8BIT>
  • 67. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256"
  • 68. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256" Ruby 2.0.0 UTF-8 is the default encoding
  • 69. UTF-8 is the default character encoding of ruby scripts # cat test.rb FOO = "222dL256" Ruby 2.0.0 UTF-8 is the default encoding Binary string literals become UTF-8 even if invalid: irb(main):001:0> require './test' => true irb(main):002:0> FOO.encoding => #<Encoding:UTF-8> irb(main):003:0> FOO.valid_encoding? => false
  • 70. UTF-8 is the default character encoding of ruby scripts So, what's the problem? Binary strings are used in many places for vm "fleecing" Invalid UTF-8 encoded strings != raw binary:
  • 71. UTF-8 is the default character encoding of ruby scripts So, what's the problem? Binary strings are used in many places for vm "fleecing" Invalid UTF-8 encoded strings != raw binary: irb(main):003:0> FOO.valid_encoding? => false irb(main):004:0> FOO == "222dL256".force_encoding("ASCII-8BIT") => false
  • 72. UTF-8 is the default character encoding of ruby scripts Solutions: Force binary on individual Strings: 1.9.3/2.0.0 compatible Painful on files with many binary string literals
  • 73. UTF-8 is the default character encoding of ruby scripts Solutions: Force binary on individual Strings: 1.9.3/2.0.0 compatible Painful on files with many binary string literals # cat test.rb FOO = "222dL256".force_encoding("ASCII-8BIT")
  • 74. UTF-8 is the default character encoding of ruby scripts Solutions: Force binary on individual Strings: 1.9.3/2.0.0 compatible Painful on files with many binary string literals # cat test.rb FOO = "222dL256".force_encoding("ASCII-8BIT") irb(main):001:0> require './test' => true irb(main):002:0> FOO.encoding => #<Encoding:ASCII-8BIT> irb(main):003:0> FOO.valid_encoding? => true irb(main):004:0> FOO == "222dL256".force_encoding("ASCII-8BIT") => true
  • 75. UTF-8 is the default character encoding of ruby scripts Solutions: Use String#b on individual strings Not compatible with ruby 1.9.3 Copies the String in ASCII-8BIT encoding Note: String#force_encoding("ASCII-8BIT") modifies the receiver
  • 76. UTF-8 is the default character encoding of ruby scripts Solutions: Add #encoding magic comment at top 1.9.3/2.0.0 compatible Good option when binary strings are expected
  • 77. UTF-8 is the default character encoding of ruby scripts Solutions: Add #encoding magic comment at top 1.9.3/2.0.0 compatible Good option when binary strings are expected # cat test.rb # encoding: US-ASCII FOO = "222dL256"
  • 78. UTF-8 is the default character encoding of ruby scripts Solutions: Add #encoding magic comment at top 1.9.3/2.0.0 compatible Good option when binary strings are expected # cat test.rb # encoding: US-ASCII FOO = "222dL256" irb(main):001:0> require './test' => true irb(main):002:0> FOO.encoding => #<Encoding:ASCII-8BIT>
  • 79. Descriptors except 0, 1, 2 are closed in child processes Prevents file descriptor leakage See Pull #682, Issue #459, and https://bugs.ruby-lang.org/issues/5041
  • 80. Descriptors except 0, 1, 2 are closed in child processes Prevents file descriptor leakage See Pull #682, Issue #459, and https://bugs.ruby-lang.org/issues/5041 Example: shared pipe to communicate data between two processes
  • 81. Descriptors except 0, 1, 2 are closed in child processes Prevents file descriptor leakage See Pull #682, Issue #459, and https://bugs.ruby-lang.org/issues/5041 Example: shared pipe to communicate data between two processes Use IO#close_on_exec = false reader, writer = IO.pipe writerfd = writer.fileno my_env["WRITER_FD"] = writerfd.to_s + + writer.close_on_exec = false + pid = Kernel.spawn(my_env, "ruby #{SERVER_PATH}VixDiskLibServer.rb", [:out, :err] => [LOG_FILE, "a"], :unsetenv_others => true,
  • 82. String#lines returns an array Also String#chars, #bytes and #codepoints Previously, returned enumerators Above are deprecated for StringIO, IO and friends
  • 83. String#lines returns an array Also String#chars, #bytes and #codepoints Previously, returned enumerators Above are deprecated for StringIO, IO and friends StringIO#lines deprecated, so use #each_line instead: @log_stream.rewind - lines = @log_stream.lines.to_a + lines = @log_stream.each_line.to_a lines.length.should == 1 line = lines.first.chomp
  • 84. String#lines returns an array Also String#chars, #bytes and #codepoints Previously, returned enumerators Above are deprecated for StringIO, IO and friends StringIO#lines deprecated, so use #each_line instead: @log_stream.rewind - lines = @log_stream.lines.to_a + lines = @log_stream.each_line.to_a lines.length.should == 1 line = lines.first.chomp See Pull #714
  • 85. Ok, great, but are we there yet???
  • 86. "Fall cleanup" of old code "...Now I've only been an OpenBSD developer for 11 years, one year less than this header has existed, but in that brief time, I've learned a thing or two about deleting obsolete code. It doesn't delete itself. And worse, people will continue using it until you force them onto a better path." http://freshbsd.org/commit/openbsd/68dc781944a2c5b90f8b6e1069a4201750c67f94
  • 87. "Fall cleanup" of old code "...Now I've only been an OpenBSD developer for 11 years, one year less than this header has existed, but in that brief time, I've learned a thing or two about deleting obsolete code. It doesn't delete itself. And worse, people will continue using it until you force them onto a better path." http://freshbsd.org/commit/openbsd/68dc781944a2c5b90f8b6e1069a4201750c67f94 Git is our friend if we really want it back
  • 88. "Fall cleanup" of old code Path to ruby 2.0...
  • 89. "Fall cleanup" of old code Path to ruby 2.0... 83 commits 565 lines added 5,553 lines deleted
  • 90. "Fall cleanup" of old code Path to ruby 2.0... 83 commits 565 lines added 5,553 lines deleted A good start?
  • 91. "Fall cleanup" of old code More "opportunities" host directory soap4r/actionwebservice (fork) handsoap (fork) - note, useful but still forked :-( ruport (fork) ziya (fork) - patches rails! prototype old rails plugins old gems old monkey patches
  • 92. Slow tests Tests take 30+ minutes on CI servers Separate tests Minimizing setup (database inserts) Remove invalid/not useful/duplicate tests Allocation tracing with ruby 2.1 Cut support for 1.9.3 when 2.0 is stable
  • 93. Building 2.0 appliances Verified Ruby 2.0 on CentOS appliance: Appliance startup SmartState Analysis "fleecing" using vddk vCenter inventory Basic reporting
  • 94. Building 2.0 appliances Goal: automate building ruby 2.0 appliances We currently use ruby 1.9.3 through SCL rpms Not multi-platform Restricts updating of some gems Ruby 2.1 is not yet packaged as SCL rpms
  • 95. Building 2.0 appliances Solution: rpms for base CentOS OS rpms needed to build ruby and compiled gems libxml2-devel, libxslt-devel, etc.
  • 96. Building 2.0 appliances Solution: rpms for base CentOS OS rpms needed to build ruby and compiled gems libxml2-devel, libxslt-devel, etc. Use ruby-install or ruby-build for building ruby https://github.com/postmodern/ruby-install https://github.com/sstephenson/ruby-build
  • 97. Building 2.0 appliances Solution: rpms for base CentOS OS rpms needed to build ruby and compiled gems libxml2-devel, libxslt-devel, etc. Use ruby-install or ruby-build for building ruby https://github.com/postmodern/ruby-install https://github.com/sstephenson/ruby-build Let bundler handle what it does well...
  • 98. Developer setup 2.0.0 is not much different from 1.9.3: Install using rvm, ruby-install, or ruby-build Manage with rvm, rbenv, or chruby Need guinea pigs to try it and document any issues Others tools, such as rubymine, may require some configuration
  • 99. Links 2.0 open issues: https://github.com/ManageIQ/manageiq/labels/ruby%202 2.0 closed issues: https://github.com/ManageIQ/manageiq/issues? q=label%3A%22ruby+2%22+is%3Aclosed 2.0 in depth: http://globaldev.co.uk/2013/03/ruby-2-0-0-in-detail/ 2.1 in depth: http://globaldev.co.uk/2014/05/ruby-2-1-in-detail/ Slides available here: https://github.com/jrafanie/manageiq_summit_ruby20 Slides written in markdown using remarkjs: http://remarkjs.com/#1