eigenclass logo
MAIN  Index  Search  Changes  PageRank  Login

Changes in Ruby 1.9, Oct. 07 update

This is a summary of the changes in Ruby 1.9 between Feb. and Oct. 07. As usual, refer to the full list for further details.

try_convert

The Array, Hash, String, IO and Regexp classes have a "try_convert" class method that either returns the converted value, as returned by to_ary, to_hash, to_string, to_io and to_regexp, or nil if the object cannot be converted for any reason.

Enumerable

each_with_index

Now forwards arguments to #each:

 [RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.9.0", "2007-08-03"]
 class X
   include Enumerable
   def each(*args); yield args.inspect end
 end
 z = nil
 X.new.each_with_index(42){|x| z = x}
 z                                                   # => ["[42]", 1]

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#cycle can be described in Ruby as follows:

 def cycle
   a = []
   each{|x| a << x; yield x}
   loop{ a.each{|x| yield x} }
 end

take

Returns either the first n elements from the enumeration or all elements until the given block returns false (ruby-dev:30407):

a = [1, 2, 3, 4, 5]
 
a.take(3)             # => [1, 2, 3]
a.take {|i| i < 3 }   # => [1, 2]

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) (ruby-dev:30407):

a = [1, 2, 3, 4, 5]
 
a.drop(3)             # => [4, 5]
a.drop {|i| i < 3 }   # => [3, 4, 5]

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

zip

Doesn't convert the arguments to arrays; enumerators are used instead.

minmax and minmax_by

Returns both the minimun and the maximum at once as a two-element array.

rewind

Rewinds the enumeration sequence.

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

ruby-list:42671

permutation

ary.permutation(n){|c| ...}

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

product

Returns the cartesian product of the receiver and the arrays given as arguments:

 [1,2,3].product([4,5])     # => [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
 [1,2].product([1,2])       # => [[1,1],[1,2],[2,1],[2,2]]
 [1,2].product([3,4],[5,6]) # => [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
                            #     [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
 [1,2].product()            # => [[1],[2]]
 [1,2].product([])          # => []

Hash

Semantics for Hash#each and Hash#each_pair

each_pair passes two arguments to the block, #each passes a two-element array to the block, so

 [RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.9.0", "2007-08-03"]
 {1 => 2}.each{|x| p x}
 {1 => 2}.each_pair{|x| p x}
 # >> [1, 2]
 # >> 1

Keep in mind that |x| is equivalent to |x,|.

select

Returns a hash instead of an association array (ruby-core:11504):

[RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.8.5", "2006-08-25"]
{'foo'=>'bar','baz'=>'qux'}.select{|k,v| k=='baz' }    # => [["baz", "qux"]]

vs.

[RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.9.0", "2007-08-03"]
{'foo'=>'bar','baz'=>'qux'}.select{|k,v| k=='baz' }    # => {"baz"=>"qux"}

Strings and symbols

Encoding-awareness; it has finally happened.

String methods operate on chars and are thus encoding-aware. These are some of the affected methods:

  • ==
  • [] []=
  • each_line, each_char
  • hash
  • inspect
  • length
  • ljust, rjust, center
  • reverse
  • split
  • strip!, strip, lstrip, rstrip
  • succ
  • upcase, downcase, capitalize, swapcase

The length field in the format specifier for printf-like methods also operates on a character basis.

String#each_char

Passes each character (not byte!) to the given block.

String#encoding

Returns the encoding of the string.

String#force_encoding

Changes the encoding of the string to the given one and returns self.

String#subseq

Operates like [] but with a byte offset and count instead of using characters.

String#upto

Takes an optional second array specifying whether the to exclude the final value (by default, it is included).

Symbol#intern

Returns self.

Symbol#encoding

Returns the encoding of the symbol.

Symbol methods similar to those in String

Now Symbols respond to many methods that resemble those in String:

  • []
  • <=>, casecmp, =~, ===
  • empty?
  • encoding
  • length, size
  • match
  • slice
  • succ, next
  • upcase, downcase, capitalize, swapcase

Regexp#match, String#match

If a block is given, it will only be evaluated and given the matchdata if there is a match.

IO

IO#getbyte, IO#readbyte, StringIO#getbyte, StringIO#readbyte

getbyte returns either a Fixnum or nil on EOF. readbyte returns a Fixnum or raises EOFError.

IO#ungetc, StringIO#ungetc

Allows to push back an arbitrarily large character.

Kernel#getc has been removed

Replaced by STDIN.getc.

Numeric#fdiv

An alias for quo (ruby-dev:30771).

New semantics for block arguments

|v| now works like the former |v,|:

[RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.8.5", "2006-08-25"]
def m; yield 1, 2; end
m{|v| v}                                          # => [1, 2] # !> multiple values for a block parameter (2 for 1)

vs.

[RUBY_VERSION, RUBY_RELEASE_DATE]                 # => ["1.9.0", "2007-08-03"]
def m; yield 1, 2; end
m{|v| v}                                          # => 1

Splats

They are also allowed in expressions like

[RUBY_VERSION, RUBY_RELEASE_DATE]                # => ["1.9.0", "2007-08-03"]
a = [1,2,3]
b = [4,5,6]
[*a, *b]                                         # => [1, 2, 3, 4, 5, 6]

printf-style formatted strings (%)

  • %c can print a one character String (as returned e.g. by ?c).
  • %u behaves like %d for negative values (ruby-core:11575)

BasicObject#funcall! is gone

It has been replaced by send! by popular demand.

Proc#lambda?

Returns whether the Proc has got "lambda semantics" or "block semantics".

Fiber: coroutines/micro-threads

Fiber#yield can be used to force a change of context amongst micro-threads. The API is being refined. ko1 has told me that matz has blessed Fibers, so they will be included in 1.9.1, even if the API is in a state of flux.



Clarifications? - Rick DeNatale (2007-10-12 (Fri) 16:04:39)

Enumerable#cycle

 It might be me, but the description is as clear as mud.

Enumerable#take

 shouldn't this say either while the block evaluates to true, or until the block evaluates to false?

Also Matz recently mentioned on either ruby or ruby-core that Hash maintains a list of keys by insertion order, and Hash#each will yield in that order.

mfp 2007-10-13 (Sat) 04:00:46

I have updated the description of #cycle. Hope it's clearer now. Also, good catch on the #take braino.

As for hashes & insertion order, it was indeed said on ruby-core:12542. I'll see if I can find further references on ruby-dev (I like to link to rationales and discussions about the implementation when possible) and add it to the list.

Thanks

Name:
Comment:
TextFormattingRules
Preview:

Yuck - Daniel Berger (2007-10-12 (Fri) 18:53:47)

Can't say I like most of these additions. Thumbs down.

Name:
Comment:
TextFormattingRules
Preview:

me neither - vruz (2007-10-12 (Fri) 19:16:57)

Whilst it's good to see the language evolving, I'd like to see more work on performance optimisation, and improving the process accepting patches that have been floating around for months if not years.

Name:
Comment:
TextFormattingRules
Preview:

Enumerable#cycle - Grant Hutchins (2007-10-12 (Fri) 19:19:15)

The way I understand it, Enumberable#cycle is like the Enumerable#each that keeps on going (looping back to the beginning) until break is called.

Name:
Comment:
TextFormattingRules
Preview:

Yuck what? - murphy (2007-10-13 (Sam) 05:38:51)

Daniel, what's the matter? Please explain.

mfp 2007-10-13 (Sat) 15:52:44

There's little to hate (or love) vehemently in this change list if you compare it with experiments that have been discarded like the new method lookup rules or the ->() block syntax. Maybe the M17N stuff or the block argument semantics?

Name:
Comment:
TextFormattingRules
Preview:

Use this form to create a new top-level comment; for direct replies to existing comments, use the text entries you'll find below.

Name:
Subject:

TextFormattingRules
Preview:
Last modified:2007/10/12 04:47:48
Keyword(s):[blog] [frontpage] [ruby] [changelog] [1.9]
References: