What is the difference between Ruby 1.8 and Ruby 1.9 What is the difference between Ruby 1.8 and Ruby 1.9 ruby ruby

What is the difference between Ruby 1.8 and Ruby 1.9


Sam Ruby has a cool slideshow that outline the differences.

In the interest of bringing this information inline for easier reference, and in case the link goes dead in the abstract future, here's an overview of Sam's slides. The slideshow is less overwhelming to review, but having it all laid out in a list like this is also helpful.

Ruby 1.9 - Major Features

  • Performance
  • Threads/Fibers
  • Encoding/Unicode
  • gems is (mostly) built-in now
  • if statements do not introduce scope in Ruby.

What's changed?

Single character strings.

Ruby 1.9

irb(main):001:0> ?c=> "c"

Ruby 1.8.6

irb(main):001:0> ?c=> 99

String index.

Ruby 1.9

irb(main):001:0> "cat"[1]=> "a"

Ruby 1.8.6

irb(main):001:0> "cat"[1]=> 97

{"a","b"} No Longer Supported

Ruby 1.9

irb(main):002:0> {1,2}SyntaxError: (irb):2: syntax error, unexpected ',', expecting tASSOC

Ruby 1.8.6

irb(main):001:0> {1,2}=> {1=>2}

Action: Convert to {1 => 2}


Array.to_s Now Contains Punctuation

Ruby 1.9

irb(main):001:0> [1,2,3].to_s=> "[1, 2, 3]"

Ruby 1.8.6

irb(main):001:0> [1,2,3].to_s=> "123"

Action: Use .join instead


Colon No Longer Valid In When Statements

Ruby 1.9

irb(main):001:0> case 'a'; when /\w/: puts 'word'; endSyntaxError: (irb):1: syntax error, unexpected ':',expecting keyword_then or ',' or ';' or '\n'

Ruby 1.8.6

irb(main):001:0> case 'a'; when /\w/: puts 'word'; endword

Action: Use semicolon, then, or newline


Block Variables Now Shadow Local Variables

Ruby 1.9

irb(main):001:0> i=0; [1,2,3].each {|i|}; i=> 0irb(main):002:0> i=0; for i in [1,2,3]; end; i=> 3

Ruby 1.8.6

irb(main):001:0> i=0; [1,2,3].each {|i|}; i=> 3

Hash.index Deprecated

Ruby 1.9

irb(main):001:0> {1=>2}.index(2)(irb):18: warning: Hash#index is deprecated; use Hash#key=> 1irb(main):002:0> {1=>2}.key(2)=> 1

Ruby 1.8.6

irb(main):001:0> {1=>2}.index(2)=> 1

Action: Use Hash.key


Fixnum.to_sym Now Gone

Ruby 1.9

irb(main):001:0> 5.to_symNoMethodError: undefined method 'to_sym' for 5:Fixnum

Ruby 1.8.6

irb(main):001:0> 5.to_sym=> nil

(Cont'd) Ruby 1.9

# Find an argument value by name or index.def [](index)  lookup(index.to_sym)end

svn.ruby-lang.org/repos/ruby/trunk/lib/rake.rb


Hash Keys Now Unordered

Ruby 1.9

irb(main):001:0> {:a=>"a", :c=>"c", :b=>"b"}=> {:a=>"a", :c=>"c", :b=>"b"}

Ruby 1.8.6

irb(main):001:0> {:a=>"a", :c=>"c", :b=>"b"}=> {:a=>"a", :b=>"b", :c=>"c"}

Order is insertion order


Stricter Unicode Regular Expressions

Ruby 1.9

irb(main):001:0> /\x80/uSyntaxError: (irb):2: invalid multibyte escape: /\x80/

Ruby 1.8.6

irb(main):001:0> /\x80/u=> /\x80/u

tr and Regexp Now Understand Unicode

Ruby 1.9

unicode(string).tr(CP1252_DIFFERENCES, UNICODE_EQUIVALENT).  gsub(INVALID_XML_CHAR, REPLACEMENT_CHAR).  gsub(XML_PREDEFINED) {|c| PREDEFINED[c.ord]}

pack and unpack

Ruby 1.8.6

def xchr(escape=true)  n = XChar::CP1252[self] || self  case n when *XChar::VALID    XChar::PREDEFINED[n] or       (n>128 ? n.chr : (escape ? "&##{n};" : [n].pack('U*')))  else    Builder::XChar::REPLACEMENT_CHAR  endendunpack('U*').map {|n| n.xchr(escape)}.join

BasicObject More Brutal Than BlankSlate

Ruby 1.9

irb(main):001:0> class C < BasicObject; def f; Math::PI; end; end; C.new.fNameError: uninitialized constant C::Math

Ruby 1.8.6

irb(main):001:0> require 'blankslate'=> trueirb(main):002:0> class C < BlankSlate; def f; Math::PI; end; end; C.new.f=> 3.14159265358979

Action: Use ::Math::PI


Delegation Changes

Ruby 1.9

irb(main):002:0> class C < SimpleDelegator; end=> nilirb(main):003:0> C.new('').class=> String

Ruby 1.8.6

irb(main):002:0> class C < SimpleDelegator; end=> nilirb(main):003:0> C.new('').class=> Cirb(main):004:0>

Defect 17700


Use of $KCODE Produces Warnings

Ruby 1.9

irb(main):004:1> $KCODE = 'UTF8'(irb):4: warning: variable $KCODE is no longer effective; ignored=> "UTF8"

Ruby 1.8.6

irb(main):001:0> $KCODE = 'UTF8'=> "UTF8"

instance_methods Now an Array of Symbols

Ruby 1.9

irb(main):001:0> {}.methods.sort.last=> :zip

Ruby 1.8.6

irb(main):001:0> {}.methods.sort.last=> "zip"

Action: Replace instance_methods.include? with method_defined?


Source File Encoding

Basic

# coding: utf-8

Emacs

# -*- encoding: utf-8 -*-

Shebang

#!/usr/local/rubybook/bin/ruby# encoding: utf-8

Real Threading

  • Race Conditions
  • Implicit Ordering Assumptions
  • Test Code

What's New?

Alternate Syntax for Symbol as Hash Keys

Ruby 1.9

{a: b}redirect_to action: show

Ruby 1.8.6

{:a => b}redirect_to :action => show

Block Local Variables

Ruby 1.9

[1,2].each {|value; t| t=value*value}

Inject Methods

Ruby 1.9

[1,2].inject(:+)

Ruby 1.8.6

[1,2].inject {|a,b| a+b}

to_enum

Ruby 1.9

short_enum = [1, 2, 3].to_enumlong_enum = ('a'..'z').to_enumloop do  puts "#{short_enum.next} #{long_enum.next}"end

No block? Enum!

Ruby 1.9

e = [1,2,3].each

Lambda Shorthand

Ruby 1.9

p = -> a,b,c {a+b+c}puts p.(1,2,3)puts p[1,2,3]

Ruby 1.8.6

p = lambda {|a,b,c| a+b+c}puts p.call(1,2,3)

Complex Numbers

Ruby 1.9

Complex(3,4) == 3 + 4.im

Decimal Is Still Not The Default

Ruby 1.9

irb(main):001:0> 1.2-1.1=> 0.0999999999999999

Regex “Properties”

Ruby 1.9

/\p{Space}/

Ruby 1.8.6

/[:space:]/

Splat in Middle

Ruby 1.9

def foo(first, *middle, last)(->a, *b, c {p a-c}).(*5.downto(1))

Fibers

Ruby 1.9

f = Fiber.new do  a,b = 0,1  Fiber.yield a  Fiber.yield b  loop do    a,b = b,a+b    Fiber.yield b  endend10.times {puts f.resume}

Break Values

Ruby 1.9

match =   while line = gets     next if line =~ /^#/     break line if line.find('ruby')   end

“Nested” Methods

Ruby 1.9

def toggle  def toggle    "subsequent times"  end  "first time"end

HTH!


One huge difference would be the move from Matz's interpreter to YARV, a bytecode virtual machine that helps significantly with performance.


Many now recommend The Ruby Programming Language over the Pickaxe - more to the point, it has all the details of the 1.8/1.9 differences.