The Ruby 2.1.0
Release is nearly a month old, so its well past time to look over the changes and uncover the features least discussed.
This release received relatively exceptional social coverage. The attention largely due to the addition of Generational Garbage collection. A bit of exploration reveals changes that may have been overlooked in the shadow of RGenGC.
private def
:def now returns a symbol, a clearer return response then the former nil
irb(main):001:0> def hello
irb(main):002:1> end
=> :hello
Coupled with new private and protected methods now take in a symbol:
class Offer
def == other
if self.class == other.class
salary == other.salary
else
super
end
end
def initialize(compensation)
@compensation = compensation
end
protected def salary
@compensation
end
end
irb(main):150:0> Offer.protected_instance_methods
=> [:salary]
Required keyword arguments
class Offer
def initialize(compensation:, position: "Engineer")
@position = position
@compensation = compensation
end
end
Mark the compensation attribute as required by omitting its default value.
irb(main):170:0> Offer.new(compensation: 70000)
=> #
irb(main):171:0> Offer.new(compensation: 70000, position: "Sales Analyst")
=> #
irb(main):172:0> Offer.new(position: "Sales Analyst")
ArgumentError: missing keyword: compensation
Enumerable.to_h
Now we can take any enumerable and derive a hash from it.
(1..10).collect{|a|[a,(a * 2)]}.to_h
Array#to_h
Array implements to_h separately
[[:name, :age], ["Matz", 48]].to_h
#to_h is a convenience method that has been a long time coming.
Refinements
Refinements build a sandboxed around the duck punching / monkey patching of core classes such as numeric.
module CurrencyDecorator
refine Numeric do
def to_currency
sprintf("%s%0.2f", { :currency => "$", :number => self})
end
end
end
class Currency
using CurrencyDecorator
def initialize(numeric)
@number = numeric.to_f.to_currency
end
end
Currency.new returns an implicit conversion of any Numeric param to a decorated stringified float conforming to currency format. All within the safe confines of Currency object.
irb(main):052:0> Currency.new 45.888
<Currency:0x007fd6db0e19b0 @number="$45.89">
irb(main):054:0> Currency.new 79987.87666767
<Currency:0x007fd6db0e19b0 @number="$79987.88">
Numeric outside Currency is unaffected.
irb(main):017:> 748.to_currency
NoMethodError: undefined method `to_currency' for 748:Fixnum
irb(main):018:0> 748.9.to_currency
NoMethodError: undefined method `to_currency' for 748.9:Float
Updates in Std lib
Vector finally implements cross product
Vector[0.6, 0, 0].cross_product Vector[0, 1.4, 0]
Leveraging GMP
The GNU Multiple Precision Arithmetic Library
Large performance increase for calculations involving Bignums
Bignum and Fixnum respond to bit_length
human_population = 10900000000
human_population.bit_length
=> 34
(human_population * human_population).bit_length
=> 67
Thats the quick tour of the less hyped changes
Next I’ll be running through Ruby Koans to explore behavioral differeinces