What Is New in Ruby 2.1
| Category | Key Changes |
|---|---|
| New Features | Refinements, Keyword Arguments, Decimal Literals, Required Keyword Arguments, Method Definition Returns Symbol |
| Performance | Generational Garbage Collection (RGenGC), Object Allocation Performance, Method Entry Structure |
| Improvements | Exception#cause, Socket.getifaddrs, String#scrub, Thread Deadlock Detection |
| Deprecated | DL, Extensions using RUBY_FUNCTION_NAME_STRING() |
How did Ruby 2.1 improve performance and memory usage?
The biggest performance win was the introduction of Generational Garbage Collection (RGenGC). This new collector separates objects into generations, which drastically reduces the number of major GC cycles needed. In practice, this means your web applications and scripts will experience fewer pauses.
Object allocation was also made faster. The internal structure for method entries (rb_method_entry_t) was optimized to be smaller, which saves memory, especially in large applications with many methods. These changes together make Ruby 2.1 feel noticeably snappier under load.
What new language features were added for method definitions?
Ruby 2.1 made method definitions more expressive and flexible. You can now define methods that require specific keyword arguments, ensuring they are always provided. A method definition itself also returns the name of the method as a symbol, which is useful for metaprogramming.
def connect(host:, port:)
# host and port are now required
end
method_name = def new_method; end
# method_name now contains :new_method
Refinements were no longer experimental, allowing you to safely monkey-patch classes within a limited scope. This matters because it provides a cleaner way to extend classes without polluting the global namespace.
How did exception handling get better?
Exception handling became much more debuggable with the new Exception#cause attribute. When you rescue one exception and raise another, the original exception is now automatically stored. This gives you the full context of what went wrong.
begin
# something that fails
rescue => e
raise MyNewError.new("Failed to process")
# e is now accessible via MyNewError#cause
end
This is a game-changer for logging and error reporting in complex applications, as you no longer lose the root cause of a failure chain.
What new APIs and library updates should I know about?
The standard library saw several useful additions. Socket.getifaddrs was introduced to fetch network interface information. String#scrub provides a clean way to replace invalid byte sequences in strings, which is essential for processing external data.
Deadlock detection for threads was also improved. The system will now check for deadlock when all threads are sleeping, helping you identify stuck programs faster. These are the kinds of utilities that simplify everyday system programming tasks in Ruby.
FAQ
Is the new GC behavior backward compatible?
Yes, the RGenGC is fully backward compatible. Your existing code will run without modification. The change is internal and aims to improve performance without breaking anything.
Can I use refinements in production now?
Absolutely. Refinements were promoted from an experimental feature to a stable language feature in Ruby 2.1. They are safe to use for scoped monkey-patching.
What happens if I don't provide a required keyword argument?
Calling a method without its required keyword arguments will now raise an ArgumentError. This makes your method contracts more explicit and catches errors early.
How do I access the original cause of an exception?
Simply call the #cause method on the rescued exception object. It will return the underlying exception that triggered the current one, making debugging nested failures straightforward.
What was deprecated and needs to be replaced?
The DL library was deprecated. For native extension work, you should use the Fiddle library instead, which is its modern replacement.