Ruby 1.9 is out!
Exciting! It was apparently put up yesterday, on Christmas. What a cool gift right? I looked through the changed maintained my Mauricio and here are /my/ favorites.
New literal hash syntax [Ruby2]
{a: "foo"} # => {:a=>"foo"}
.() and calling Procs without #call/#[] [EXPERIMENTAL]
You can now do:
a = lambda{|*b| b} a.(1,2) # => [1, 2]
Multiple splats allowed
1.9 allows multiple splat operators when calling a method:
def foo(*a)
a
end
foo(1, *[2,3], 4, *[5,6]) # => [1, 2, 3, 4, 5, 6]
Mandatory arguments after optional arguments allowed
def m(a, b=nil, *c, d)
[a,b,c,d]
end
m(1,2) # => [1, nil, [], 2]
Object#tap
Passes the object to the block and returns it (meant to be used for call chaining).
"F".tap{|x| x.upcase!}[0] # => "F" # Note that "F".upcase\![0] would fail since upcase! would return nil in this # case.
Module#attr is an alias of attr_reader
Use
attr :foo=
to create a read/write accessor. (RCR#331)
Enumerable#cycle
Calls the given block for each element of the enumerable in a never-ending cycle:
a = ["a", "b", "c"]
a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
Enumerable#group_by
Groups the values in the enumerable according to the value returned by the block:
(1..10).group_by{|x| x % 3} # => {0=>[3, 6, 9], 1=>[1, 4, 7, 10], 2=>[2, 5, 8]}
Enumerable#drop
Without a block, returns an array with all but the first n elements from the enumeration. Otherwise drops elements while the block returns true (and returns all the elements after it returns a false value):
a = [1, 2, 3, 4, 5] a.drop(3) # => [4, 5]
a.drop {|i| i < 3 } # => [3, 4, 5]
Enumerable#inject (#reduce) without a block
If no block is given, the first argument to #inject is the name of a two-argument method that will be called; the optional second argument is the initial value:
[RUBY_VERSION, RUBY_RELEASE_DATE] # => ["1.9.0", "2007-08-03"] (1..10).reduce(:+) # => 55
Enumerable#count
It could be defined in Ruby as
def count(*a) inject(0) do |c, e| if a.size == 1 # suspect, but this is how it works (a[0] == e) ? c + 1 : c else yield(e) ? c + 1 : c end end end
Therefore
["bar", 1, "foo", 2].count(1) # => 1 ["bar", 1, "foo", 2].count{|x| x.to_i != 0} # => 2
Array#nitems
It is equivalent to selecting the elements that satisfy a condition and obtaining the size of the resulting array:
%w[1 2 3 4 5 6].nitems{|x| x.to_i > 3} # => 3
Block argument to Array#index, Array#rindex [Ruby2]
They can now take a block to make them work like #select.
['a','b','c'].index{|e| e == 'b'} # => 1 ['a','b','c'].index{|e| e == 'c'} # => 2 ['a','a','a'].rindex{|e| e == 'a'} # => 2 ['a','a','a'].index{|e| e == 'b'} # => nil
Array#combination
ary.combination(n){|c| ...}
yields all the combinations of length n of the elements in the array to the given block. If no block is passed, it returns an enumerator instead. The order of the combinations is unspecified.
a = [1, 2, 3, 4] a.combination(1).to_a #=> \[[1],[2],[3],[4]] a.combination(2).to_a #=> \[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] a.combination(3).to_a #=> \[[1,2,3],[1,2,4],[1,3,4],[2,3,4]] a.combination(4).to_a #=> \[[1,2,3,4]] a.combination(0).to_a #=> \[[]]: one combination of length 0 a.combination(5).to_a #=> [] : no combinations of length 5
Array#permutation
Operates like #combination, but with permutations of length n.
a = [1, 2, 3] a.permutation(1).to_a #=>; \[[1],[2],[3]] a.permutation(2).to_a #=>; \[[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] a.permutation(3).to_a #=>; \[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] a.permutation(0).to_a #=>; \[[]]: one permutation of length 0 a.permutation(4).to_a #=>; [] : no permutations of length 4
Array#pop, Array#shift
They can take an argument to specify how many objects to return:
%w[a b c d].pop(2) # =>; ["c", "d"]
Hash preserves order!
RUBY_VERSION # => "1.9.0"
h=\{:a=>;1, :b=>;2, :c=>;3, :d=>;4\} # =>; \{:a=>;1, :b=>;2, :c=>;3, :d=>;4\}
h[:e]=5
h # => {:a=>;1, :b=>;2, :c=>;3, :d=>;4, :e=>;5}
h.keys # => [:a, :b, :c, :d, :e]
h.values # => [1, 2, 3, 4, 5]
h.to_a # => \[[:a, 1], [:b, 2], [:c, 3], [:d, 4], [:e, 5]]
vs.
RUBY_VERSION # => "1.8.6"
h={:a=>1, :b=>2, :c=>3, :d=>4} # => {:a=>1, :b=>2, :c=>3, :d=>4}
h[:e]=5
h # => {:e=>5, :a=>1, :b=>2, :c=>3, :d=>4}
h.keys # => [:e, :a, :b, :c, :d]
h.values # => [5, 1, 2, 3, 4]
h.to_a # => \[[:e, 5], [:a, 1], [:b, 2], [:c, 3], [:d, 4]]
Numeric#upto, #downto, #times, #step
These methods return an enumerator if no block is given:
a = 10.times a.inject{|s,x| s+x } # => 45 a = [] b = 10.downto(5) b.each{|x| a << x} a # => [10, 9, 8, 7, 6, 5]
Range#cover?
range.cover?(value)
compares value to the begin and end values of the range, returning true if it is comprised between them, honoring #exclude_end?.
("a".."z").cover?("c") # => true
("a".."z").cover?("5") # => false
Limit input in IO#gets, IO#readline, IO#readlines, IO#each_line, IO#lines, IO.foreach, IO.readlines, StringIO#gets, StringIO#readline, StringIO#each, StringIO#readlines
These methods accept an optional integer argument to specify the maximum amount of data to be read. The limit is specified either as the (optional) second argument, or by passing a single integer argument (i.e. the first argument is interpreted as the limit if it’s an integer, as a line separator otherwise).
IO#ungetc, StringIO#ungetc
Allows to push back an arbitrarily large character.
Seven predicate methods where added for the weekdays:
Time.now # => Thu Nov 03 18:58:25 CET 2005
Time.now.sunday? # => false
Posted Wed, Dec 26, 2007If you're interested in being notified when new posts are published, you can subscribe here; you'll get an email once a week at the most.