Bruce Williams
Rubyist since 2001
Perpetrator of much random Ruby hackery, language tourist
(Full-time since 2005)
Open source developer, contributer, technical editor, designer Occasionally blogs at http://codefluency.com
Ruby 1.8
Stable. The syntax and language features you know and probably love. The performance profile you know and might hate a little.
Ruby 1.9
Unstable, transitional. Many new syntax and language features. Better performance, especially for computationally intensive operations.
1.9 is a hint.
1.9 is a hint.
Get ready for 2.0.
Standard Library + ~ rubygems (+ prelude & ruby --disable-gems), rake, json (pure, ext), ripper, probeprofiler, securerandom, HMAC digests csv replaced by FasterCSV implementation soap, wsdl, base64, some rarely used, old libraries
Parser ChangesFlexibility and Obscurity (for the moment)
Parser Changes- New Hash Literal
{a: "foo"} # => {:a=>"foo"} {a: "bar", :b => "baz"} # => {:a=>"bar", :b=>"baz"} - New Proc Literal
multiply_by_2 = ->(x) { x * 2 } # => # multiply_by_2.(4) # => 8 - Splat more flexibly
names = %w(joe john bill) [*names, 'jack'] # => ["joe", "john", "bill", "jack"] - Method parameter ordering
def say(language=:english, text) puts Translator[language].translate(text) end say "hello" # hello say :spanish, "hello" # hola
Migration Risk FactorsText processing “Clever” assignment with blocks Some Hash enumerations Metaprogramming, code generation
Tests are GoodI 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
Block Local VariablesArguments are always local
Ruby 1.8
item = 1 2.upto(4) do |item| p item end # Outputs: # 2 # 3 # 4 item # => 4
Ruby 1.9
item = 1 2.upto(4) do |item| p item end # Outputs: # 2 # 3 # 4 item # => 1
Shadowing VariablesYou’ll get a warning
Ruby 1.8
i=1 lambda { |i| p i }.call(3) # Outputs #3 i # => 3
Ruby 1.9
i=1 lambda { |i| p i }.call(3) # Outputs #3 i # => 1
-e:2: warning: shadowing outer local variable - i
Shadowing VariablesLocals, but warned
No local, reassigns
d=2 -> { d = 1 }.() d # => 1
Local, shadowedd=2 ->(;d) { d = 1 }.() d # => 2
-e:2: warning: shadowing outer local variable - d
(Ruby 1.9)
Hash#select (etc)
Ruby 1.8
conferences.select do |data| p data end # [:euruko, "Prague"] # [:scotland_on_rails, "Edinburgh"] # [:railsconf_europe, "Berlin"]
Changes to yielded argumentsRuby 1.9
conferences.select do |data| p data end # :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.8
conferences.select do |name, _| name == :scotland_on_rails end # => [[:scotland_on_rails, "Edinburgh"]]
Ruby 1.9
conferences.select do |name, _| name == :scotland_on_rails end # => {: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_885 9_1, :ISO_8859_2, :ISO_8859_3, :ISO_8859_4, :ISO_8859_5, :ISO_8859_6, :ISO_8859_7, :IS O_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, :I BM437, :CP437, :IBM737, :CP737, :IBM775, :CP775, :CP850, :IBM850, :IBM852, :CP852, :IBM85 5, :CP855, :IBM857, :CP857, :IBM860, :CP860, :IBM861, :CP861, :IBM862, :CP862, :IBM863, :CP 863, :IBM864, :CP864, :IBM865, :CP865, :IBM866, :CP866, :IBM869, :CP869, :Windows_1258, : WINDOWS_1258, :CP1258, :GB1988, :MacCentEuro, :MACCENTEURO, :MacCroatian, :MA CCROATIAN, :MacCyrillic, :MACCYRILLIC, :MacGreek, :MACGREEK, :MacIceland, :MACICE LAND, :MacRoman, :MACROMAN, :MacRomania, :MACROMANIA, :MacThai, :MACTHAI, :M acTurkish, :MACTURKISH, :MacUkraine, :MACUKRAINE, :CP950, :EucJP, :EUCJP, :EucJP_ms, :E UCJP_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, :ISO 8859_1, :Windows_1252, :WINDOWS_1252, :CP1252, :ISO8859_2, :Windows_1250, :WIN DOWS_1250, :CP1250, :ISO8859_3, :ISO8859_4, :ISO8859_5, :ISO8859_6, :Windows_1256, :WINDOWS_1256, :CP1256, :ISO8859_7, :Windows_1253, :WINDOWS_1253, :CP1253, :IS O8859_8, :Windows_1255, :WINDOWS_1255, :CP1255, :ISO8859_9, :Windows_1254, :WI NDOWS_1254, :CP1254, :ISO8859_10, :ISO8859_11, :TIS_620, :Windows_874, :WINDOW S_874, :CP874, :ISO8859_13, :Windows_1257, :WINDOWS_1257, :CP1257, :ISO8859_14, :I SO8859_15, :ISO8859_16, :CP878, :SJIS, :Windows_31J, :WINDOWS_31J, :CP932, :CsWindo ws31J, :CSWINDOWS31J, :MacJapanese, :MACJAPANESE, :MacJapan, :MACJAPAN, :ASCII, :A NSI_X3_4_1968, :UTF_7, :CP65000, :CP65001, :UCS_2BE, :UCS_4BE, :UCS_4LE, :CP1251]
Read a file with File.read
File.read("input.txt").encoding # => #
File.read("input.txt", encoding: 'ascii-8bit').encoding # => #
Read a file with File.open
result = File.open("input.txt", "r:euc-jp") do |f| f.read end result.encoding # => # result.valid_encoding? # => true
Regular Expressions
Integrated “oniguruma” engine Same basic API Much better performance Support for encodings Extended Syntax
Look-ahead (?=), (?!), look-behind (?<), (?), backreferences, etc
Named Groups
"His name is Joe".match(/name is (?\S+)/)[:name] # => "Joe"
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| "#{name} is #{offset + 1}" end # => ["Joe is #1", "John is #2", "Jack is #3"]
Enumerable
reduce (inject)
[1,2,3,4].reduce(:+) # => 10
New Enumerable methods take, group_by, drop, min_by, max_by, count, and others.
take
array = [1, 2, 3, 4, 5] array.take(3) # => [1, 2, 3] array # => [1, 2, 3, 4, 5]
drop
array = [1, 2, 3, 4, 5] array.drop(3) # => [4, 5] array # => [1, 2, 3, 4, 5]
Hash Changes
Insertion 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"
Object
Added tap
thing = Thing.new.tap do |thing| thing.something = 1 thing.something_else = 2 end
Lambda Changes
Obfuscation, ahoy!
New literal syntax more flexible Not possible in { | | ... } style literals
Passing blocks
m = ->(x, &b) { b.(x * 2) if b } m.(3) do |result| puts result end # Output #6
Default arguments
->(a, b=2) { a * b }.(3) # => 6
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
:foo[1] # => "o"
Comparing with a String
:this === "this" # => true
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...
This was really just an introduction.
Bruce Williams
bruce@codefluency.com
http://www.scribd.com/doc/2589469/Migrating-to-Ruby-19