¿Cuál es la diferencia entre Ruby 1.8 y Ruby 1.9?

102

No tengo claras las diferencias entre la versión "actual" de Ruby (1.8) y la versión "nueva" (1.9). ¿Existe una explicación "fácil" o "simple" de las diferencias y por qué son tan diferentes?

sal. corredor
fuente
1
Supongo que te refieres a Ruby 1.8.6 - Ruby 1.8.7 tiene muchas construcciones de bibliotecas desde 1.9.
Andrew Grimm
Más considero que las versiones 1.8 son las versiones "antiguas" y 1.9.2+ las "actuales". Solo uso 1.8.7 para verificaciones de compatibilidad, pero desarrollo en 1.9.2.
The Tin Man
5
@Telemachus: El enlace está roto.
Andrew Grimm
1
@Telemachus, Andrew Grimm - este enlace de archive.org funciona - web.archive.org/web/20090423003136/http://eigenclass.org/…
J.Merrill

Respuestas:

170

Sam Ruby tiene una presentación de diapositivas genial que describe las diferencias .

Con el fin de incorporar esta información en línea para facilitar la referencia, y en caso de que el enlace falle en un futuro abstracto, aquí hay una descripción general de las diapositivas de Sam. La presentación de diapositivas es menos abrumadora de revisar, pero tener todo en una lista como esta también es útil.

Ruby 1.9 - Características principales

  • Actuación
  • Hilos / Fibras
  • Codificación / Unicode
  • las gemas están (en su mayoría) integradas ahora
  • si las declaraciones no introducen alcance en Ruby.

¿Qué ha cambiado?

Cadenas de un solo carácter.

Rubí 1.9

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

Ruby 1.8.6

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

Índice de cadena.

Rubí 1.9

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

Ruby 1.8.6

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

{"a", "b"} Ya no es compatible

Rubí 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}

Acción: convertir a {1 => 2}


Array.to_s Ahora contiene puntuación

Rubí 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"

Acción: utilice .join en su lugar


Los dos puntos ya no son válidos en declaraciones cuando

Rubí 1.9

irb(main):001:0> case 'a'; when /\w/: puts 'word'; end
SyntaxError: (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'; end
word

Acción: use punto y coma, luego o nueva línea


Las variables de bloque ahora sombrean las variables locales

Rubí 1.9

irb(main):001:0> i=0; [1,2,3].each {|i|}; i
=> 0
irb(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 Obsoleto

Rubí 1.9

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

Ruby 1.8.6

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

Acción: Use Hash.key


Fixnum.to_sym Ahora ido

Rubí 1.9

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

Ruby 1.8.6

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

(Continuación) 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


Teclas hash ahora desordenadas

Rubí 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"}

El pedido es un pedido de inserción


Expresiones regulares Unicode más estrictas

Rubí 1.9

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

Ruby 1.8.6

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

try Regexpahora entiende Unicode

Rubí 1.9

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

pack y 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
  end
end
unpack('U*').map {|n| n.xchr(escape)}.join

BasicObject Más brutal que BlankSlate

Rubí 1.9

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

Ruby 1.8.6

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

Acción: Use :: Math :: PI


Cambios de delegación

Rubí 1.9

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

Ruby 1.8.6

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

Defecto 17700


El uso de $ KCODE produce advertencias

Rubí 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 Ahora una matriz de símbolos

Rubí 1.9

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

Ruby 1.8.6

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

Acción: ¿ Reemplazar instance_methods.include? con method_defined?


Codificación del archivo de origen

Básico

# coding: utf-8

Emacs

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

El asunto

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

Enhebrado real

  • Condiciones de carrera
  • Supuestos de ordenación implícitos
  • Código de prueba

¿Qué hay de nuevo?

Sintaxis alternativa para símbolo como teclas hash

Rubí 1.9

{a: b}

redirect_to action: show

Ruby 1.8.6

{:a => b}

redirect_to :action => show

Bloquear variables locales

Rubí 1.9

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

Métodos de inyección

Rubí 1.9

[1,2].inject(:+)

Ruby 1.8.6

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

to_enum

Rubí 1.9

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

¿Sin bloque? Enum!

Rubí 1.9

e = [1,2,3].each

Taquigrafía Lambda

Rubí 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)

Números complejos

Rubí 1.9

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

Decimal aún no es el valor predeterminado

Rubí 1.9

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

Regex "Propiedades"

Rubí 1.9

/\p{Space}/

Ruby 1.8.6

/[:space:]/

Splat en el medio

Rubí 1.9

def foo(first, *middle, last)

(->a, *b, c {p a-c}).(*5.downto(1))

Fibras

Rubí 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
  end
end
10.times {puts f.resume}

Romper valores

Rubí 1.9

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

Métodos "anidados"

Rubí 1.9

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

HTH!

Tim Sullivan
fuente
3
HTH == "Espero que ayude". Tenía que ver eso. ¿Puede señalarme una respuesta que proporcionó, en la que no esperaba que ayudara?
Chris Wesseling
¿O te refieres a Happy to help? Edite en consecuencia. O elimínelo, si su felicidad / esperanza cuenta para todas sus respuestas. ;-)
Chris Wesseling
10
No, lo dejaré como está. Como porcentaje de la respuesta total, es minúsculo y cualquier interpretación me parece bien. Gracias.
Tim Sullivan
Según el enlace que proporcionó, el cambio en la delegación fue un error y se ha corregido.
Kyle Strand
¿Qué pasa con la inconsistencia entre "Range.include?" ¿método? Ruby v1.8.7 da un resultado diferente al v1.9
Lucas Pottersky
12

Una gran diferencia sería el cambio del intérprete de Matz a YARV , una máquina virtual de código de bytes que ayuda significativamente con el rendimiento.

Sören Kuklau
fuente
4

Muchos ahora recomiendan The Ruby Programming Language sobre el Pickaxe; más concretamente, tiene todos los detalles de las diferencias 1.8 / 1.9.

Dave Everitt
fuente
1
Me gustan los dos. El libro Pickaxe analiza algunas cosas con más detalle, pero el lenguaje de programación Ruby es bueno cuando quieres buscar algo rápidamente. Está más cerca de un libro "en pocas palabras".
The Tin Man
1

Algunos cambios más:

Devolviendo una matriz de singleton splat:

def function
  return *[1]
end

a=function
  • rubí 1.9: [1]
  • rubí 1.8: 1

argumentos de matriz

def function(array)
  array.each { |v| p v }
end
function "1"
  • ruby 1.8: "1"
  • ruby 1.9: método indefinido `each 'para" 1 ": String
Wim Yedema
fuente