Upload
codefluency
View
2.066
Download
2
Embed Size (px)
DESCRIPTION
Slides from Boston.rb talk on September 9th, 2008
Citation preview
Ruby 1.9New in
Bruce Williams
Thanks for having me out to Boston.
(especially to Thoughtbot & Tammer for the couch surfing opportunity)
Bruce Williams
Language Geek
lojbanesperantoarabic
basque
spanish
german
russian
erlang
ruby perl
python
c
java
haskellocaml
io
self
smalltalk
objc
english
lisp c++
awkeiffel
2001...2005Rubyist
2005..2008:-) + $:-)
Open Source DeveloperRTeX, TuneUp, keyword_search, numerous Rails
plugins
A bunch of URLshttp://codefluency.com
http://github.com/bruce
http://fiveruns.com
http://twitter.com/wbruce
and 1.9?
YARV
1.9 is just like 1.7.Except completely
different.
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
1.9.1 will be stable.
Expect it around Christmas.
Many new syntax and language features.
Not strictly backwards compatible to 1.8.
Better performance characteristics.
More bugs (it’s new!)
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
$ 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/
$ 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!)
Standard Library Changes
soap, wsdl, base64, some rarely used, old libraries
rubygems, rake, json, ripper, probeprofiler, securerandom, HMAC digests
csv replaced by FasterCSV implementation
12
3
Risk FactorsMigration
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>
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*’).
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]"كلمات"
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.”
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.
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.
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.
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!
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.
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
New Features
XL
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)
[: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]
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
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
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
Enumerable
[1,2,3,4].reduce(:+)# => 10
[1,2,3,4].reduce(&:+)# => 10
Reduce (inject) SymbolorSymbol#to_proc
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
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
thing = Thing.new.tap do |thing| thing.something = 1 thing.something_else = 2end
Object
Tap
{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
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
-> 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.!
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
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”):
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
Questions?