Migrating to Ruby 1.9

Post on 12-Nov-2014

4768 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

Transcript

Ruby 1.9Migrating to

Bruce Williams

Bruce WilliamsRubyist since 2001

Open source developer, contributer, technical editor, designerOccasionally blogs at http://codefluency.com

(Full-time since 2005)

Perpetrator of much random Ruby hackery, language tourist

Stable.

The syntax and language features you know and probably love.

The performance profile you know and might hate a little.

Unstable, transitional.

Many new syntax and language features.

Better performance, especially for computationally intensive operations.

Ruby 1.9Ruby 1.8

1.9 is a hint.

1.9 is a hint.Get ready for 2.0.

1.8.61.8.51.8.4

1.8.31.8.21.8.1

1.8.01.6.81.6.71.6.21.6.1

1.6.01.5

1.71.9

1.6.41.6.51.6.3

Japan Beyond Japan “... on Rails” Expansion

‘00 ‘01 ‘02 ‘03 ‘04 ‘05 ‘06 ‘07 ‘08

(dev)(dev)

Ruby’s ReleasesFrom Toybox to Toolshed

(dev)

Standard Library

+rubygems (+ prelude & ruby --disable-gems), rake, json (pure,

ext), ripper, probeprofiler, securerandom, HMAC digests

- soap, wsdl, base64, some rarely used, old libraries

~ csv replaced by FasterCSV implementation

Parser ChangesFlexibility and Obscurity (for the moment)

{a: "foo"}# => {:a=>"foo"}

{a: "bar", :b => "baz"}# => {:a=>"bar", :b=>"baz"}

Parser ChangesNew Hash Literal

Parser ChangesNew Proc Literal

multiply_by_2 = ->(x) { x * 2 }# => #<Proc:0x3c5a50>

multiply_by_2.(4)# => 8

Parser ChangesSplat more flexibly

names = %w(joe john bill)[*names, 'jack']# => ["joe", "john", "bill", "jack"]

Parser ChangesMethod parameter ordering

def say(language=:english, text) puts Translator[language].translate(text)endsay "hello"# hellosay :spanish, "hello"# hola

Text processing

“Clever” assignment with blocks

Some Hash enumerations

Metaprogramming, code generation

Migration Risk Factors

I was surprised at how much work my 11th hour integration of the FasterCSV code was. It was a pure Ruby library that really didn't do a lot of fancy tricks, but I had to track down about 20 little issues to get it running under Ruby 1.9. Thank goodness it had terrific test coverage to lead me to the problem areas.

- James Edward Gray II

Tests are Good

Follow-up at http://blog.grayproductions.net/articles/getting_code_ready_for_ruby_19

Block Local VariablesArguments are always local

item = 12.upto(4) do |item| p itemend# Outputs:# 2# 3# 4item# => 4

item = 12.upto(4) do |item| p itemend# Outputs:# 2# 3# 4item# => 1

Ruby 1.9Ruby 1.8

Shadowing VariablesYou’ll get a warning

Ruby 1.9Ruby 1.8

i = 1lambda { |i| p i }.call(3)# Outputs# 3i# => 3

i = 1lambda { |i| p i }.call(3)# Outputs# 3i# => 1

-e:2: warning: shadowing outer local variable - i

Shadowing VariablesLocals, but warned

-e:2: warning: shadowing outer local variable - d

d = 2->(;d) { d = 1 }.()d# => 2

d = 2-> { d = 1 }.()d# => 1

(Ruby 1.9)

No local, reassigns Local, shadowed

Hash#select (etc)Changes to yielded arguments

Ruby 1.9Ruby 1.8conferences.select do |data| p dataend# [:euruko, "Prague"]# [:scotland_on_rails, "Edinburgh"]# [:railsconf_europe, "Berlin"]

conferences.select do |data| p dataend# :euruko# :scotland_on_rails# :railsconf_europe

conferences.select do |name, city| p [name, city]end# [:euruko, "Prague"]# [:scotland_on_rails, "Edinburgh"]# [:railsconf_europe, "Berlin"]

warning: multiple values for a block parameter (2 for 1)

Hash#select (etc)Returns a Hash

Ruby 1.9Ruby 1.8conferences.select do |name, _| name == :scotland_on_railsend# => [[:scotland_on_rails, "Edinburgh"]]

conferences.select do |name, _| name == :scotland_on_railsend# => {:scotland_on_rails=>"Edinburgh"}

FeaturesLots of changes,

some big ones

Multilingualization(m17n)

There is one type of string, and the encoding is mutable

Strings are no longer Enumerable (use #each_char, #each_line, etc)

The encoding is ‘lazy’ and can be set by probing with

String#ascii_only? and String#valid_encoding?. 

Various ways to set default encoding (commandline, magic comments)

String#[] now returns a String, not a Fixnum (use ord)

[:ASCII_8BIT, :Big5, :BIG5, :CP949, :EUC_JP, :EUC_KR, :EUC_TW, :GB18030, :GBK, :ISO_8859_1, :ISO_8859_2, :ISO_8859_3, :ISO_8859_4, :ISO_8859_5, :ISO_8859_6, :ISO_8859_7, :ISO_8859_8, :ISO_8859_9, :ISO_8859_10, :ISO_8859_11, :ISO_8859_13, :ISO_8859_14, :ISO_8859_15, :ISO_8859_16, :KOI8_R, :KOI8_U, :Shift_JIS, :SHIFT_JIS, :US_ASCII, :UTF_8, :UTF_16BE, :UTF_16LE, :UTF_32BE, :UTF_32LE, :Windows_1251, :WINDOWS_1251, :BINARY, :IBM437, :CP437, :IBM737, :CP737, :IBM775, :CP775, :CP850, :IBM850, :IBM852, :CP852, :IBM855, :CP855, :IBM857, :CP857, :IBM860, :CP860, :IBM861, :CP861, :IBM862, :CP862, :IBM863, :CP863, :IBM864, :CP864, :IBM865, :CP865, :IBM866, :CP866, :IBM869, :CP869, :Windows_1258, :WINDOWS_1258, :CP1258, :GB1988, :MacCentEuro, :MACCENTEURO, :MacCroatian, :MACCROATIAN, :MacCyrillic, :MACCYRILLIC, :MacGreek, :MACGREEK, :MacIceland, :MACICELAND, :MacRoman, :MACROMAN, :MacRomania, :MACROMANIA, :MacThai, :MACTHAI, :MacTurkish, :MACTURKISH, :MacUkraine, :MACUKRAINE, :CP950, :EucJP, :EUCJP, :EucJP_ms, :EUCJP_MS, :EUC_JP_MS, :CP51932, :EucKR, :EUCKR, :EucTW, :EUCTW, :EUC_CN, :EucCN, :EUCCN, :GB12345, :CP936, :ISO_2022_JP, :ISO2022_JP, :ISO_2022_JP_2, :ISO2022_JP2, :ISO8859_1, :Windows_1252, :WINDOWS_1252, :CP1252, :ISO8859_2, :Windows_1250, :WINDOWS_1250, :CP1250, :ISO8859_3, :ISO8859_4, :ISO8859_5, :ISO8859_6, :Windows_1256, :WINDOWS_1256, :CP1256, :ISO8859_7, :Windows_1253, :WINDOWS_1253, :CP1253, :ISO8859_8, :Windows_1255, :WINDOWS_1255, :CP1255, :ISO8859_9, :Windows_1254, :WINDOWS_1254, :CP1254, :ISO8859_10, :ISO8859_11, :TIS_620, :Windows_874, :WINDOWS_874, :CP874, :ISO8859_13, :Windows_1257, :WINDOWS_1257, :CP1257, :ISO8859_14, :ISO8859_15, :ISO8859_16, :CP878, :SJIS, :Windows_31J, :WINDOWS_31J, :CP932, :CsWindows31J, :CSWINDOWS31J, :MacJapanese, :MACJAPANESE, :MacJapan, :MACJAPAN, :ASCII, :ANSI_X3_4_1968, :UTF_7, :CP65000, :CP65001, :UCS_2BE, :UCS_4BE, :UCS_4LE, :CP1251]

MultilingualizationRead a file with File.read

File.read("input.txt").encoding# => #<Encoding:UTF-8>

File.read("input.txt", encoding: 'ascii-8bit').encoding# => #<Encoding:ASCII-8BIT>

MultilingualizationRead a file with File.open

result = File.open("input.txt", "r:euc-jp") do |f| f.readendresult.encoding# => #<Encoding:EUC-JP>result.valid_encoding?# => true

Regular ExpressionsIntegrated “oniguruma” engine

Same basic API

Much better performance

Support for encodings

Extended Syntax

Look-ahead (?=), (?!), look-behind (?<), (?<!)

Named groups (?<>), backreferences, etc

Regular ExpressionsNamed Groups

"His name is Joe".match(/name is (?<name>\S+)/)[:name]# => "Joe"

EnumerableEnumerator built-in, returned from Enumerable methods (and those in Array, Dir, Hash, IO, Range, String or Struct that serve the same purposes). Added Enumerator#with_index

%w(Joe John Jack).map.with_index do |name, offset| "#{name} is #{offset + 1}"end# => ["Joe is #1", "John is #2", "Jack is #3"]

Map with index

Enumerablereduce (inject)

[1,2,3,4].reduce(:+)# => 10

Enumerable

take

New Enumerable methods take, group_by, drop, min_by, max_by, count, and others.

array = [1, 2, 3, 4, 5]array.take(3)# => [1, 2, 3]array# => [1, 2, 3, 4, 5]

array = [1, 2, 3, 4, 5]array.drop(3)# => [4, 5]array# => [1, 2, 3, 4, 5]

drop

Hash ChangesInsertion order preserved

conferences = { euruko: 'Prague', scotland_on_rails: 'Edinburgh'}conferences[:railsconf_europe] = 'Berlin'conferences.each do |name, city| p "#{name} is in #{city}"end# "euruko is in Prague"# "scotland_on_rails is in Edinburgh"# "railsconf_europe is in Berlin"conferences.delete(:scotland_on_rails)conferences[:scotland_on_rails] = 'Edinburgh'conferences.each do |name, city| p "#{name} is in #{city}"end# "euruko is in Prague"# "railsconf_europe is in Berlin"# "scotland_on_rails is in Edinburgh"

thing = Thing.new.tap do |thing| thing.something = 1 thing.something_else = 2end

ObjectAdded tap

Lambda ChangesObfuscation, ahoy!

New literal syntax more flexible

Not possible in { | | ... } style literals

m = ->(x, &b) { b.(x * 2) if b }m.(3) do |result| puts resultend# Output# 6

->(a, b=2) { a * b }.(3)# => 6

Passing blocks Default arguments

Symbol ChangesLess sibling rivalry

Indexing into Comparing with a String

Added to_proc

Added =~, [] like String (to_s less needed), sortable

Object#methods, etc now return an array of symbols

:foo[1]# => "o"

:this === "this"# => true

Similar to Python’s generators

Owe method naming lineage to Lua

Out of scope of the talk, but very cool

For some examples, see:

http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html (and follow-up)

http://www.davidflanagan.com/blog/2007_08.html (older)

Revactor project (Actors in 1.9 using Fibers + Threads)

InfoQ, others...

Fibers“Semi-coroutines”

This was really just an introduction.

Bruce Williams bruce@codefluency.com twitter: wbruce

top related