47
Ruby 1.9 New in Bruce Williams

New in Ruby 1 9

Embed Size (px)

DESCRIPTION

Slides from Boston.rb talk on September 9th, 2008

Citation preview

Page 1: New in Ruby 1 9

Ruby 1.9New in

Bruce Williams

Page 2: New in Ruby 1 9

Thanks for having me out to Boston.

(especially to Thoughtbot & Tammer for the couch surfing opportunity)

Page 3: New in Ruby 1 9
Page 4: New in Ruby 1 9

Bruce Williams

Page 5: New in Ruby 1 9

Language Geek

lojbanesperantoarabic

basque

spanish

german

russian

erlang

ruby perl

python

c

java

haskellocaml

io

self

smalltalk

objc

english

lisp c++

awkeiffel

Page 6: New in Ruby 1 9

2001...2005Rubyist

2005..2008:-) + $:-)

Page 7: New in Ruby 1 9

Open Source DeveloperRTeX, TuneUp, keyword_search, numerous Rails

plugins

Page 8: New in Ruby 1 9

A bunch of URLshttp://codefluency.com

http://github.com/bruce

http://fiveruns.com

http://twitter.com/wbruce

Page 9: New in Ruby 1 9

and 1.9?

Page 10: New in Ruby 1 9

YARV

Page 11: New in Ruby 1 9

1.9 is just like 1.7.Except completely

different.

Page 12: New in Ruby 1 9

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)

(dev)

1.8.7

... 2.0

1.9.1

...

StableReleases

Page 13: New in Ruby 1 9

1.9.1 will be stable.

Expect it around Christmas.

Page 14: New in Ruby 1 9

Many new syntax and language features.

Not strictly backwards compatible to 1.8.

Better performance characteristics.

More bugs (it’s new!)

1.9

Page 15: New in Ruby 1 9

Many new syntax and language features.

Not strictly backwards compatible to 1.8.

Better performance characteristics.

More bugs (it’s new!)

Out of scope.

(I’m not psychic)

1.9

Page 16: New in Ruby 1 9

$ svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby1.9$ cd ruby1.9$ autoconf$ ./configure --program-suffix=1.9$ make && sudo make install

Installing

From Subversion:

1.9.0:

http://www.ruby-lang.org/en/downloads/

Page 17: New in Ruby 1 9

$ git clone git://github.com/bruce/compare-1-9.git $ cd compare-1-9$ rake db:migrate$ ruby script/server

Comparison App

(use ruby 1.8!)

Page 18: New in Ruby 1 9

Standard Library Changes

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

rubygems, rake, json, ripper, probeprofiler, securerandom, HMAC digests

csv replaced by FasterCSV implementation

Page 19: New in Ruby 1 9

12

3

Risk FactorsMigration

Page 20: New in Ruby 1 9

Having good test coverage is very helpful when migrating code from 1.8 to 1.9.

<obligatory-testing-related-slide bdd-buzzword-compliant=”0”>

</obligatory-testing-related-slide>

Page 21: New in Ruby 1 9

Risk: Text Processing

Relying on $KCODE, String#[], or String internals. Parsers especially at risk.

? New encoding support, String#[] returns chr, not ord

Use new encoding conventions.Get familiar with String#ord and unpack(‘c*’).

Page 22: New in Ruby 1 9

Risk: Text Processing

"ruby"[0]# => 114

"ruby"[0]# => “r”

Ruby 1.9Ruby 1.8

"ruby".unpack('U*')# => [114, 117, 98, 121]

[0]"كلمات"# => 217 <= #"ك"

[0]"كلمات"

.unpack('U*')# => [1603, 1604, 1605, 1575, 1578]"كلمات"

Page 23: New in Ruby 1 9

Risk: Block Var Scope

Modifying variables outside the scope of a block with a block argument. “Clever” block tricks.

? Block variables are always local, and you get warnings when shadowing outer local variables

Modify the outer variable manually from insidethe block if needed. Stop being “clever.”

Page 24: New in Ruby 1 9

Risk: Block Var Scope

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“clever”assignment

Shadowing.Still a bad idea. Use a different name.

Page 25: New in Ruby 1 9

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

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

Ruby 1.9not declaring local

Risk: Block Var Scope

Ruby 1.9declaring local

changed the outer variable this didn’t, but you still get the shadowing warning.

Page 26: New in Ruby 1 9

Risk: Hash#select

?

Expecting an Array result from Hash#select, or capturing both key and value in a single block argument.

Hash#select now returns a ... Hash, and it’s arity-aware.

Check your loops on results from Hash#select.You may be able to remove some Hashre-creation code.

Page 27: New in Ruby 1 9

Risk: Hash Enumerations

Ruby 1.9Ruby 1.8conferences.select do |name, _| name == :lsrcend# => [[:lsrc, "Austin"]]

conferences.select do |name, _| name == :lsrcend# => {:lsrc=>"Austin"}

Hash#select returns a Hash. Yes!

Page 28: New in Ruby 1 9

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

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

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

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

Risk: Hash EnumerationsArity matters with Hash#select.

Page 29: New in Ruby 1 9

Risk: Gems

The biggest obstacle to Ruby 1.9’s adoption is the sheer number of mostly working but essentially unmaintained gems that virtually everybody in the Ruby community depends on

Help!

- Sam Ruby

Page 30: New in Ruby 1 9

New Features

XL

Page 31: New in Ruby 1 9

Multilingualization(m17n)

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

Strings don’t have #each (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)

# encoding: utf-8

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

Page 32: New in Ruby 1 9

[: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]

Page 33: New in Ruby 1 9

Regular Expressions

Integrated the “Oniguruma” engine鬼車Same basic APIMuch better performanceSupport for encodingsExtended Syntax Look-ahead (?=), (?!), look-behind (?<), (?<!)

Named groups (?<>), backreferences, etc

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

Named Groups

Page 34: New in Ruby 1 9

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>

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

Read a file with File.open

Page 35: New in Ruby 1 9

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

Page 36: New in Ruby 1 9

Enumerable

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

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

Reduce (inject) SymbolorSymbol#to_proc

Page 37: New in Ruby 1 9

EnumerableNew 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]

Take Drop

Page 38: New in Ruby 1 9

Hash Changes

conferences = { lsrc: 'Austin', scotland_on_rails: 'Edinburgh'}conferences[:rubyconf] = 'Orlando'conferences.each do |name, city| p "#{name} is in #{city}"end# "lsrc is in Austin"# "scotland_on_rails is in Edinburgh"# "rubyconf is in Orlando"conferences.delete(:scotland_on_rails)conferences[:scotland_on_rails] = 'Edinburgh'conferences.each do |name, city| p "#{name} is in #{city}"end# "lsrc is in Austin"# "rubyconf is in Orlando"# "scotland_on_rails is in Edinburgh"

Insertion Order

Page 39: New in Ruby 1 9

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

Object

Tap

Page 40: New in Ruby 1 9

{foo: 1, bar: 2}# => {:foo=>1, :bar=>2}

{foo: 1, 'bar' => 2, 'foo' => 3}# => {:foo=>1, "bar"=>2, "foo"=>3}

some_method "argument1", a: 1, b: 2

Symbol shortcut

You can mix forms

And leave it `open’

New Hash Literal

Page 41: New in Ruby 1 9

New Proc LiteralMore 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

Page 42: New in Ruby 1 9

-> a = 1, b = 2, c, &d ; e { e = d.(a * b * c); e + 1 }.(3) { |p| p * 4 }# => 25

Can be Ugly as Hell

Don’t do this. Ruby isn’t Perl.!

Page 43: New in Ruby 1 9

Symbol Changes

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

Page 44: New in Ruby 1 9

ThreadsMoved to a native threading model.

A thread has mutex (GVL: Global VM Lock) can run. When thread scheduling, running thread release GVL. If running thread try blocking operation, this thread must release GVL and another thread can continue this flow. After blocking operation, thread must check interrupt (RUBY_VM_CHECK_INTS).

Every VM can run parallel.

Ruby threads are scheduled by OS thread scheduler.

From thread.c (“model 2”):

Page 45: New in Ruby 1 9

Fibers

http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html

http://www.davidflanagan.com/blog/2007_08.html

InfoQ, others...

“Semi-coroutines.” Think of them as lightweight user threads with manual scheduling.

Revactor

NeverBlock

Page 46: New in Ruby 1 9

Questions?