fREWdiculous!
26 Dec
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]*
1 | {a: "foo"} # => {:a=>"foo"} |
*.() and calling Procs without #call/#[] [EXPERIMENTAL]*
You can now do:
1 | a = lambda{|*b| b} a.(1,2) # => [1, 2] |
*Multiple splats allowed*
1.9 allows multiple splat operators when calling a method:
1 2 3 4 5 | def foo(*a) a end foo(1, *[2,3], 4, *[5,6]) # => [1, 2, 3, 4, 5, 6] |
*Mandatory arguments after optional arguments allowed*
1 2 3 4 | 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).
1 | "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
1 | 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:
1 2 | 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 | (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):
1 2 | 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:
1 | [RUBY_VERSION, RUBY_RELEASE_DATE] # => ["1.9.0", "2007-08-03"] (1..10).reduce(:+) # => 55 |
*Enumerable#count*
It could be defined in Ruby as
1 | 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
1 | ["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:
1 | %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.
1 | ['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*
1 | 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.
1 | 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*
1 2 | Operates like #combination, but with permutations of length n. <code lang="ruby">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:
1 | %w[a b c d].pop(2) # => ["c", "d"] |
*Hash preserves order!*
1 2 3 4 5 6 7 8 | 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.
1 2 3 4 5 6 7 | 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:
1 | 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?*
1 | 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?.
1 2 | ("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:*
1 2 | Time.now # => Thu Nov 03 18:58:25 CET 2005 Time.now.sunday? # => false |
3 Responses for "Ruby 1.9 is out!"
This part right here:
a = [1, 2, 3, 4, 5] a.drop(3) # => [4, 5] a.drop {|i| i < 3 } # => [3, 4, 5]
wasn’t really making sense to me? Typo maybe?
Darry: I fixed the typo. Does it make more sense now?
Reformat, please, code sample for *Array#permutation*
Leave a reply