2. Bruce Williams
Perpetrator of much random Ruby hackery, language tourist
Rubyist since 2001 (Full-time since 2005)
Open source developer, contributer, technical editor, designer
Occasionally blogs at http://codefluency.com
3. Ruby 1.8 Ruby 1.9
Stable. Unstable, transitional.
The syntax and language Many new syntax and
features you know and language features.
probably love.
Better performance,
The performance profile especially for computationally
you know and might hate intensive operations.
a little.
11. Parser Changes
Splat more flexibly
names = %w(joe john bill)
[*names, 'jack']
# => [quot;joequot;, quot;johnquot;, quot;billquot;, quot;jackquot;]
12. Parser Changes
Method parameter ordering
def say(language=:english, text)
puts Translator[language].translate(text)
end
say quot;helloquot;
# hello
say :spanish, quot;helloquot;
# hola
13. Migration Risk Factors
Text processing
“Clever” assignment with blocks
Some Hash enumerations
Metaprogramming, code generation
14. Tests are Good
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
Follow-up at http://blog.grayproductions.net/articles/getting_code_ready_for_ruby_19
15. Block Local Variables
Arguments are always local
Ruby 1.8 Ruby 1.9
item = 1 item = 1
2.upto(4) do |item| 2.upto(4) do |item|
p item p item
end end
# Outputs: # Outputs:
# 2 # 2
# 3 # 3
# 4 # 4
item item
# => 4 # => 1
16. Shadowing Variables
You’ll get a warning
Ruby 1.8 Ruby 1.9
i=1 i=1
lambda { |i| p i }.call(3) lambda { |i| p i }.call(3)
# Outputs # Outputs
#3 #3
i i
# => 3 # => 1
-e:2: warning: shadowing outer local variable - i
17. Shadowing Variables
Locals, but warned
No local, reassigns Local, shadowed
d=2 d=2
-> { d = 1 }.() ->(;d) { d = 1 }.()
d d
# => 1 # => 2
(Ruby 1.9) -e:2: warning: shadowing outer local variable - d
18. Hash#select (etc)
Changes to yielded arguments
Ruby 1.8 Ruby 1.9
conferences.select do |data| conferences.select do |data|
p data p data
end end
# [:euruko, quot;Praguequot;] # :euruko
# [:scotland_on_rails, quot;Edinburghquot;] # :scotland_on_rails
# [:railsconf_europe, quot;Berlinquot;] # :railsconf_europe
conferences.select do |name, city|
warning: multiple values for a block parameter (2 for 1)
p [name, city]
end
# [:euruko, quot;Praguequot;]
# [:scotland_on_rails, quot;Edinburghquot;]
# [:railsconf_europe, quot;Berlinquot;]
19. Hash#select (etc)
Returns a Hash
Ruby 1.8 Ruby 1.9
conferences.select do |name, _| conferences.select do |name, _|
name == :scotland_on_rails name == :scotland_on_rails
end end
# => [[:scotland_on_rails, quot;Edinburghquot;]] # => {:scotland_on_rails=>quot;Edinburghquot;}
21. 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)
23. Multilingualization
Read a file with File.read
File.read(quot;input.txtquot;).encoding
# => #<Encoding:UTF-8>
File.read(quot;input.txtquot;, encoding: 'ascii-8bit').encoding
# => #<Encoding:ASCII-8BIT>
24. Multilingualization
Read a file with File.open
result = File.open(quot;input.txtquot;, quot;r:euc-jpquot;) do |f|
f.read
end
result.encoding
# => #<Encoding:EUC-JP>
result.valid_encoding?
# => true
25. Regular Expressions
Integrated “oniguruma” engine
Same basic API
Much better performance
Support for encodings
Extended Syntax
Look-ahead (?=), (?!), look-behind (?<), (?<!)
Named groups (?<>), backreferences, etc
27. Enumerable
Enumerator 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
Map with index
%w(Joe John Jack).map.with_index do |name, offset|
quot;#{name} is #{offset + 1}quot;
end
# => [quot;Joe is #1quot;, quot;John is #2quot;, quot;Jack is #3quot;]
30. Hash Changes
Insertion order preserved
conferences = {
euruko: 'Prague',
scotland_on_rails: 'Edinburgh'
}
conferences[:railsconf_europe] = 'Berlin'
conferences.each do |name, city|
p quot;#{name} is in #{city}quot;
end
# quot;euruko is in Praguequot;
# quot;scotland_on_rails is in Edinburghquot;
# quot;railsconf_europe is in Berlinquot;
conferences.delete(:scotland_on_rails)
conferences[:scotland_on_rails] = 'Edinburgh'
conferences.each do |name, city|
p quot;#{name} is in #{city}quot;
end
# quot;euruko is in Praguequot;
# quot;railsconf_europe is in Berlinquot;
# quot;scotland_on_rails is in Edinburghquot;
31. Object
Added tap
thing = Thing.new.tap do |thing|
thing.something = 1
thing.something_else = 2
end
32. Lambda Changes
Obfuscation, ahoy!
New literal syntax more flexible
Not possible in { | | ... } style literals
Passing blocks Default arguments
m = ->(x, &b) { b.(x * 2) if b } ->(a, b=2) { a * b }.(3)
m.(3) do |result|
# => 6
puts result
end
# Output
#6
33. Symbol Changes
Less sibling rivalry
Added to_proc
Added =~, [] like String (to_s less needed), sortable
Object#methods, etc now return an array of symbols
Indexing into Comparing with a String
:foo[1] :this === quot;thisquot;
# => true
# => quot;oquot;
34. Fibers
“Semi-coroutines”
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...
35. This was really just an introduction.
Bruce Williams twitter: wbruce
bruce@codefluency.com