eigenclass logo
MAIN  Index  Search  Changes  PageRank  Login

Dissecting matz's monster patch: lots of activity in 1.9 (2006-06)

At last, enough commit activity on HEAD to justify an update to my summary of changes in Ruby 1.9. It looked as if almost nothing had happened in the last three months (Akira's work on the non-blocking IO stuff and little more) and then came matz's gigantic patch with a load of Ruby2 features...

Syntax

Those who don't understand the meaning of the word "experimental" and foreboded Ruby's demise in the arcane syntax pit and, well, pretty much any Rubyist out there ;), will be happy to know that the ;; terminator and the ->(){} lambda notation are is dead!

Some new syntax arrived to take the place of these syntactical failures, but it blends quite nicely with 1.8's.

As suggested by Audrey Tang, you can use several splat operators in a method call:

def foo(*a)
  a
end

foo(1, *[2,3], 4, *[5,6])                        # => [1, 2, 3, 4, 5, 6]

A slightly bolder addition allows you to use splats, "assocs" (hashes without braces) and block arguments with #[]:

RUBY_VERSION                                       # => "1.9.0"
RUBY_RELEASE_DATE                                  # => "2006-06-11"
class Foo; def [](*a, &block); block.call(a) end end

a = (0..3).to_a
Foo.new[*a, :op => :+]{|x| x }                     # => [0, 1, 2, 3, {:op=>:+}]

One character Strings

String#[] now returns a one-char-wide String instead of a Fixnum; String#[]=, IO#getc and the ?c syntax were changed accordingly. The new String#ord allows you to get your friendly Fixnum out of the String returned by String#[], so

'a'[0].ord

is equivalent 'a'[0] in 1.8.

Misc. new methods

A bunch of non-blocking methods in IO, Socket, TCPServer and UNIXServer, Proc#yield, __method__ and __callee__, Math#log2...

Summary of changes since the last update

  • Math#log accepts an optional base argument (ruby-talk:191308)
  • Math#log2 added (ruby-talk:191237)
  • lots of new methods for non-blocking IO: IO#read_nonblock, IO#write_nonblock, Socket#connect_nonblock, Socket#accept_nonblock, Socket#revcfrom_nonblock ruby-core:7917, IPSocket#recvfrm_nonblock, UNIXSocket#recvfrom_nonblock, TCPServer#accept_nonblock, UNIXServer#accept_nonblock
  • String#[] returns a one-char-wide String instead of a Fixnum [Ruby2]
  • String#[]= doesn't support fixnum insertion anymore (ie. str[2] = 2 won't work]
  • IO#getc returns a one character String instead of a Fixnum
  • ?c returns a single character String instead of a Fixnum [Ruby2]
  • #[] can take any kind of arguments: "assocs" (hashes without braces), splat, block arguments
  • added Proc#yield (also NilClass#yield which raises a LocalJumpError so you can use it on &block); quoting from the RDoc:
 Invokes the block, setting the block's parameters to the values in
 params in the same manner the yield statement does.
    
    a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
    a_proc.yield(9, 1, 2, 3)   #=> [9, 18, 27]
    a_proc.yield([9, 1, 2, 3]) #=> [9, 18, 27]
    a_proc = Proc.new {|a,b| a}
    a_proc.yield(1,2,3)	  # => [1]
  • more than one splat in the argument list is allowed
  • the ;; terminator is gone
  • the ->(){ } notation for blocks is gone: you need an explicit & to turn the lambda into a block
  • printf-style format strings: %c can print a one character String (as returned e.g. by ?c)
  • new global methods: __method__ and __callee__
  • new method: String#ord: returns the Integer ordinal of a one-character string.
   "a".ord         #=> 97
  • Symbol#to_proc: first discovered by some anonymous Japanese Rubyist (fairly certain), rediscovered by Florian Groß (I saw that happen back when I wasted my time on #ruby-lang), then popularized by Pragdave and Rails, finally adopted officially. It's been a long journey.

Trivia

String#hash uses a new hash algorithm (Fowler/Noll/Vo FNV-1a ). See http://www.isthe.com/chongo/tech/comp/fnv/index.html .

Further information

You can also take a look at the updated 1.8 vs. 1.9 Changelog in full.

Closing thought

Would matz make smaller ("atomic") commits if he didn't have to use CVS and was able to do offline commits (say with svk)?


-> - Matt Todd (2006-06-12 (Mon) 03:15:56)

I kinda like the -> notation, reminds me of Haskell (et al). Things are looking great! I'm excited about this upcoming release (whenever that may be). Hope the pick-axe gets updated quickly thereafter.

M.T.

Matt Todd 2006-06-12 (Mon) 03:57:39

By the way, I can't find anything about ';;' so I have no idea what it was meant to do to begin with. (I didn't find anything about it in your previous post, either.) What did it do?

mfp 2006-06-12 (Mon) 04:04:18

;; used to be equivalent to end, so you could do

 class Foo 
   def bar
   # ....
 ;;;;

(I removed the description from the change summary since it's dead now.)

Matt Todd 2006-06-12 (Mon) 09:41:49

Yeah, that is quite un-Rubylike. Good thing it's gone. :) But, again, I like the -> :D


log notation - Martin DeMello (2006-06-11 (Sun) 11:24:30)

Good news about log2, but it's a shame redefining log() to mean log10() and ln() to mean log_e() would break too much code to happen. Would bring ruby back in line with practically everyone else, including mathematicians and scientists.

String#[] - Pawel (2006-06-11 (Sun) 05:14:38)

Bravo for the one character string feature! I've often wondered why it was set up to return the numeric representation of the ascii code.

mfp 2006-06-11 (Sun) 05:26:06

Returning a Fixnum was consistent with the "String as an array of bytes" view. "foo"[0] == 'f' is a small step towards "strings of characters", but we'll have to wait for further M17N stuff and all the new encoding magic.

riffraff 11-06-2006 (Dom) 05:52:39

/me saw Symbol#to_proc rediscovering too in ye ole days :°°)

BTW, I nice news is that now we can even have arguments following splats in the method def, i.e.

def foo(*a,needed)

(seen as "eval.c (formal_assign): handles post splat argument")

Daniel Berger 2006-06-11 (Sun) 07:54:32

And there was much rejoicing. Well, we'll see how keyword arguments turn out. :)

Urabe, Shyouhei 2006-06-11 (�) 08:31:45

No, ->(){} style lambdas are not gone. Try it for yourself.

mfp 2006-06-11 (Sun) 11:37:13

oops. I thought I'd read somewhere that ->(){} was to be removed altogether, and misread an entry in the Changelog (parse.y (do_block): remove -> style block.).


Last modified:2006/06/11 11:41:11
Keyword(s):[blog] [ruby] [frontpage] [1.9] [changelog] [update]
References:[Line numbers, error reporting and backtraces]