Quelle est la différence entre Ruby 1.8 et Ruby 1.9

102

Je ne suis pas clair sur les différences entre la version "actuelle" de Ruby (1.8) et la "nouvelle" version (1.9). Existe-t-il une explication «facile» ou «simple» des différences et pourquoi elles sont si différentes?

salt.racer
la source
1
Je suppose que vous voulez dire Ruby 1.8.6 - Ruby 1.8.7 a beaucoup de constructions de bibliothèques à partir de 1.9.
Andrew Grimm
De plus, je considère les versions 1.8 comme les "anciennes" versions, et 1.9.2+ les "actuelles". Je n'utilise que la version 1.8.7 pour les vérifications de compatibilité mais je développe en 1.9.2.
the Tin Man
5
@Telemachus: Le lien est rompu.
Andrew Grimm
1
@Telemachus, Andrew Grimm - ce lien archive.org fonctionne - web.archive.org/web/20090423003136/http
//eigenclass.org

Réponses:

170

Sam Ruby a un diaporama sympa qui décrit les différences .

Dans l'intérêt de mettre ces informations en ligne pour une référence plus facile, et au cas où le lien disparaîtrait dans un avenir abstrait, voici un aperçu des diapositives de Sam. Le diaporama est moins fastidieux à examiner, mais tout présenter dans une liste comme celle-ci est également utile.

Ruby 1.9 - Principales fonctionnalités

  • Performance
  • Fils / Fibres
  • Encodage / Unicode
  • gems est (principalement) intégré maintenant
  • si les instructions n'introduisent pas de portée dans Ruby.

Qu'est-ce qui a changé?

Chaînes de caractères uniques.

Rubis 1.9

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

Rubis 1.8.6

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

Index de chaîne.

Rubis 1.9

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

Rubis 1.8.6

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

{"a", "b"} Plus pris en charge

Rubis 1.9

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

Rubis 1.8.6

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

Action: convertir en {1 => 2}


Array.to_s Contient maintenant la ponctuation

Rubis 1.9

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

Rubis 1.8.6

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

Action: utilisez plutôt .join


Colon n'est plus valide dans les déclarations When

Rubis 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'

Rubis 1.8.6

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

Action: utilisez un point-virgule, puis ou une nouvelle ligne


Bloquer les variables maintenant Observer les variables locales

Rubis 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

Rubis 1.8.6

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

Hash.index Obsolète

Rubis 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

Rubis 1.8.6

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

Action: utilisez Hash.key


Fixnum.to_sym Maintenant parti

Rubis 1.9

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

Rubis 1.8.6

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

(Suite) Rubis 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


Clés de hachage désormais non ordonnées

Rubis 1.9

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

Rubis 1.8.6

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

L'ordre est l'ordre d'insertion


Expressions régulières Unicode plus strictes

Rubis 1.9

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

Rubis 1.8.6

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

tret Regexpmaintenant comprendre Unicode

Rubis 1.9

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

pack et unpack

Rubis 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 Plus brutal que BlankSlate

Rubis 1.9

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

Rubis 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

Action: Utilisez :: Math :: PI


Changements de délégation

Rubis 1.9

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

Rubis 1.8.6

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

Défaut 17700


L'utilisation de $ KCODE génère des avertissements

Rubis 1.9

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

Rubis 1.8.6

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

instance_methods Maintenant un tableau de symboles

Rubis 1.9

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

Rubis 1.8.6

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

Action: remplacez instance_methods.include? avec method_defined?


Encodage du fichier source

De base

# coding: utf-8

Emacs

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

Case

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

Filetage réel

  • Conditions de course
  • Hypothèses de classement implicites
  • Code de test

Quoi de neuf?

Syntaxe alternative pour le symbole en tant que clés de hachage

Rubis 1.9

{a: b}

redirect_to action: show

Rubis 1.8.6

{:a => b}

redirect_to :action => show

Bloquer les variables locales

Rubis 1.9

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

Méthodes d'injection

Rubis 1.9

[1,2].inject(:+)

Rubis 1.8.6

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

to_enum

Rubis 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

Pas de blocage? Enum!

Rubis 1.9

e = [1,2,3].each

Sténographie Lambda

Rubis 1.9

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

Rubis 1.8.6

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

Nombres complexes

Rubis 1.9

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

La décimale n'est toujours pas la valeur par défaut

Rubis 1.9

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

Regex «Propriétés»

Rubis 1.9

/\p{Space}/

Rubis 1.8.6

/[:space:]/

Splat au milieu

Rubis 1.9

def foo(first, *middle, last)

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

Les fibres

Rubis 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}

Casser les valeurs

Rubis 1.9

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

Méthodes "imbriquées"

Rubis 1.9

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

HTH!

Tim Sullivan
la source
3
HTH == "J'espère que ça aide". J'ai dû chercher ça. Pouvez-vous m'indiquer une réponse que vous avez fournie, dans laquelle vous n'espériez pas qu'elle aiderait?
Chris Wesseling le
Ou vouliez-vous dire Heureux d'aider? Veuillez modifier en conséquence. Ou supprimez-le, si votre bonheur / espoir compte pour toutes vos réponses. ;-)
Chris Wesseling
10
Non, je vais le laisser tel quel. En pourcentage de la réponse totale, c'est minuscule et l'une ou l'autre des interprétations me convient. Merci.
Tim Sullivan
D'après le lien que vous avez fourni, le changement de délégation était un bogue et a été corrigé.
Kyle Strand
Qu'en est-il de l'incohérence entre "Range.include?" méthode? Ruby v1.8.7 donne un résultat différent de la v1.9
Lucas Pottersky
12

Une énorme différence serait le passage de l'interpréteur de Matz à YARV , une machine virtuelle bytecode qui améliore considérablement les performances.

Sören Kuklau
la source
4

Beaucoup recommandent maintenant le langage de programmation Ruby plutôt que la pioche - plus précisément, il contient tous les détails des différences 1.8 / 1.9.

Dave Everitt
la source
1
Je les aime tous les deux. Le livre Pickaxe traite de certaines choses plus en détail, mais le langage de programmation Ruby est bon lorsque vous souhaitez rechercher rapidement quelque chose. C'est plus proche d'un livre «en bref».
The Tin Man
1

Quelques changements supplémentaires:

Retour d'un tableau de singleton splat:

def function
  return *[1]
end

a=function
  • rubis 1.9: [1]
  • rubis 1,8: 1

arguments de tableau

def function(array)
  array.each { |v| p v }
end
function "1"
  • rubis 1.8: "1"
  • ruby 1.9: méthode non définie `each 'pour" 1 ": chaîne
Wim Yedema
la source