“Good Parts” “The real paradigm shift is in the fact that Ruby was designed to make programming fast, enjoyable and easy instead of being optimized for machines running it.” – Matt Aimonetti http://merbist.com/2009/11/16/the-ruby-revolution-take-ii/
us “I was delighted to refect on the thought that they were right there in the values of Ward, Kent, and all the other people who've been advocating clean code, well-factored object-oriented design, and testability. These ideas have made a great impact on many other technological communi- ties, but in Ruby-land they are the orthodoxy.” – Martin Fowler http://www.martinfowler.com/bliki/RailsConf2007.html
• The problem is on method definition: def obj.method(arg, hash) lots = Hash[:lots] || "default" args = Hash[:args] || "another" hand = Hash[:by hand] || "annoying" … end Hand-written code == root cause of bugs
syntactic updates • Symbol array literal %i and %I introduced. • Ruby now thinks its inputs to be UTF-8 encoded by default. You can of course specify other encodings explicitly. %i(foo bar baz) # => [:foo, :bar, :baz]
• Background: today as we have gems, booting ruby up tends to require 128+ libraries at once, resulting poor experience. • Solution: require got faster (in sense of com- putational complexity). – Several techniques to reduce computations.
generation • Since the beginning, backtraces has been arrays of strings. • Each time an exception was raised, these strings were generated from up to down, even when that was not actually used. – Can get ultra slow when you have 1024+ stack frames (typical Rails situation).
generation • Starting ruby 2.x, Thread::Backtrace are used instead of strings. – Which are very lightweight. • When you need to look at the backtrace, just convert them to strings (call #to_s).
• On a 64bit machine (ubiquitous these days), pointers, integers and foating-point numbers are all 64bit width. • In ruby, pointers and integers are C level register variables. But double was stored on-memory. What if we can handle them like pointers?
• Bitmap marking: GC mark bits were in every objects, but moved into a dedicated memory page to reduce cache misshits (also much more CoW friendly). • Nonrecursive marking: mark function now avoids the risk of machine stack overfow. • Lazy sweep (since 1.9.3): sweeper collects only what's necessary (reduces stop time).
• You can probe live production Ruby behaviour in non-stop, non-overhead fashion. • Supports Solaris (dtrace), Mac OS X (dtrace), and Linux (SystemTrap). • http://bugs.ruby-lang.org/projects/ruby/wiki/DTraceProbes
Interrupt Handling • Background: ruby execution sometimes gets interrupted for various reasons, e.g. timeout. timeout(rand()) do setup handle teardown end Complete Russian Roulette on where it gets interrupted!
Interrupt Handling Thread.async_interrupt_timing Timeout::Error => :defer do timeout(rand()) do begin Thread.async_interrupt_timing Timeout::Error => :immediate do setup handle … end ensure teardown end end end
Interrupt Handling Thread.async_interrupt_timing Timeout::Error => :defer do timeout(rand()) do begin Thread.async_interrupt_timing Timeout::Error => :immediate do setup handle … end ensure teardown end end end Blue area gets interrupted Red area does not.
• Sometimes you want to add setup / teardown of a method defined elswhere. module ActiveRecordHelper def save ??? end end Wanna setup/teardown but how do we do that?
• Ruby's foo.bar.baz. … style (so-called being “fuent”) sometimes requires unnecessary temporary object to pass around, which can theoretically be avoided by lazy evaluations.
new in Ruby 2 • Almost everything. • “100% backward compatible”, said matz. • (for instance) Rails runs as-is. • Don't be afraid! Just start using 2.0.0!
said, • New things are added • Also lots of internal improvements • Even if you are already confident about your current environment, 2.0.0 is worth looking at.