Migrating to Ruby 1.9

Download Migrating to Ruby 1.9

Post on 12-Nov-2014




3 download

Embed Size (px)


<p>Ruby 1.9</p> <p>Migrating to</p> <p>Bruce Williams</p> <p>Bruce WilliamsRubyist since 2001</p> <p>Perpetrator of much random Ruby hackery, language tourist</p> <p>(Full-time since 2005)</p> <p>Open source developer, contributer, technical editor, designer Occasionally blogs at http://codeuency.com</p> <p>Ruby 1.8Stable. The syntax and language features you know and probably love. The performance prole you know and might hate a little.</p> <p>Ruby 1.9Unstable, transitional. Many new syntax and language features. Better performance, especially for computationally intensive operations.</p> <p>1.9 is a hint.</p> <p>1.9 is a hint.Get ready for 2.0.</p> <p>Rubys ReleasesFrom Toybox to Toolshed(dev) 1.5 1.6.1 1.6.3 1.6.5 1.6.0 1.6.2 1.6.4 1.6.7 (dev) 1.7 1.6.8 1.8.1 1.8.0 1.8.4 1.8.2 1.8.3 1.8.5 1.8.6 (dev) 1.9</p> <p>00</p> <p>01</p> <p>02</p> <p>03</p> <p>04</p> <p>05</p> <p>06</p> <p>07</p> <p>08</p> <p>Japan</p> <p>Beyond Japan</p> <p>... on Rails</p> <p>Expansion</p> <p>Standard Library + ~ rubygems (+ prelude &amp; ruby --disable-gems), rake, json (pure, ext), ripper, probeproler, securerandom, HMAC digests csv replaced by FasterCSV implementation soap, wsdl, base64, some rarely used, old libraries</p> <p>Parser Changes</p> <p>Flexibility and Obscurity (for the moment)</p> <p>Parser ChangesNew Hash Literal{a: "foo"} # =&gt; {:a=&gt;"foo"} {a: "bar", :b =&gt; "baz"} # =&gt; {:a=&gt;"bar", :b=&gt;"baz"}</p> <p>Parser ChangesNew Proc Literalmultiply_by_2 = -&gt;(x) { x * 2 } # =&gt; # multiply_by_2.(4) # =&gt; 8</p> <p>Parser ChangesSplat more exiblynames = %w(joe john bill) [*names, 'jack'] # =&gt; ["joe", "john", "bill", "jack"]</p> <p>Parser ChangesMethod parameter orderingdef say(language=:english, text) puts Translator[language].translate(text) end say "hello" # hello say :spanish, "hello" # hola</p> <p>Migration Risk FactorsText processing Clever assignment with blocks Some Hash enumerations Metaprogramming, code generation</p> <p>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 terric test coverage to lead me to the problem areas.</p> <p>- James Edward Gray IIFollow-up at http://blog.grayproductions.net/articles/getting_code_ready_for_ruby_19</p> <p>Block Local VariablesArguments are always local</p> <p>Ruby 1.8item = 1 2.upto(4) do |item| p item end # Outputs: # 2 # 3 # 4 item # =&gt; 4</p> <p>Ruby 1.9item = 1 2.upto(4) do |item| p item end # Outputs: # 2 # 3 # 4 item # =&gt; 1</p> <p>Shadowing VariablesYoull get a warning</p> <p>Ruby 1.8i = 1 lambda { |i| p i }.call(3) # Outputs # 3 i # =&gt; 3</p> <p>Ruby 1.9i = 1 lambda { |i| p i }.call(3) # Outputs # 3 i # =&gt; 1-e:2: warning: shadowing outer local variable - i</p> <p>Shadowing VariablesLocals, but warnedNo local, reassignsd = 2 -&gt; { d = 1 }.() d # =&gt; 1</p> <p>Local, shadowedd = 2 -&gt;(;d) { d = 1 }.() d # =&gt; 2-e:2: warning: shadowing outer local variable - d</p> <p>(Ruby 1.9)</p> <p>Hash#select (etc)Ruby 1.8conferences.select do |data| p data end # [:euruko, "Prague"] # [:scotland_on_rails, "Edinburgh"] # [:railsconf_europe, "Berlin"]</p> <p>Changes to yielded arguments</p> <p>Ruby 1.9conferences.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"]</p> <p>warning: multiple values for a block parameter (2 for 1)</p> <p>Hash#select (etc)Returns a Hash</p> <p>Ruby 1.8conferences.select do |name, _| name == :scotland_on_rails end # =&gt; [[:scotland_on_rails, "Edinburgh"]]</p> <p>Ruby 1.9conferences.select do |name, _| name == :scotland_on_rails end # =&gt; {:scotland_on_rails=&gt;"Edinburgh"}</p> <p>FeaturesLots of changes, some big ones</p> <p>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)</p> <p>[: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]</p> <p>MultilingualizationRead a le with File.readFile.read("input.txt").encoding # =&gt; # File.read("input.txt", encoding: 'ascii-8bit').encoding # =&gt; #</p> <p>MultilingualizationRead a le with File.openresult = File.open("input.txt", "r:euc-jp") do |f| f.read end result.encoding # =&gt; # result.valid_encoding? # =&gt; true</p> <p>Regular ExpressionsIntegrated oniguruma engine Same basic API Much better performance Support for encodings Extended SyntaxLook-ahead (?=), (?!), look-behind (?\S+)/)[:name] # =&gt; "Joe"</p> <p>EnumerableEnumerator built-in, returned from Enumerable methods (andthose in Array, Dir, Hash, IO, Range, String or Struct that serve the same purposes). Added Enumerator#with_index</p> <p>Map with index%w(Joe John Jack).map.with_index do |name, offset| "#{name} is #{offset + 1}" end # =&gt; ["Joe is #1", "John is #2", "Jack is #3"]</p> <p>Enumerablereduce (inject)</p> <p>[1,2,3,4].reduce(:+) # =&gt; 10</p> <p>EnumerableNew Enumerable methods take, group_by, drop, min_by, max_by, count, and others.</p> <p>takearray = [1, 2, 3, 4, 5] array.take(3) # =&gt; [1, 2, 3] array # =&gt; [1, 2, 3, 4, 5]</p> <p>droparray = [1, 2, 3, 4, 5] array.drop(3) # =&gt; [4, 5] array # =&gt; [1, 2, 3, 4, 5]</p> <p>Hash ChangesInsertion order preservedconferences = { 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"</p> <p>ObjectAdded tap</p> <p>thing = Thing.new.tap do |thing| thing.something = 1 thing.something_else = 2 end</p> <p>Lambda ChangesObfuscation, ahoy!New literal syntax more exible Not possible in { | | ... } style literals</p> <p>Passing blocksm = -&gt;(x, &amp;b) { b.(x * 2) if b } m.(3) do |result| puts result end # Output # 6</p> <p>Default arguments-&gt;(a, b=2) { a * b }.(3) # =&gt; 6</p> <p>Symbol ChangesLess sibling rivalryAdded to_proc Added =~, [] like String (to_s less needed), sortable Object#methods, etc now return an array of symbols</p> <p>Indexing into:foo[1] # =&gt; "o"</p> <p>Comparing with a String:this === "this" # =&gt; true</p> <p>Fibers</p> <p>Semi-coroutinesSimilar to Pythons 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.davidanagan.com/blog/2007_08.html (older) Revactor project (Actors in 1.9 using Fibers + Threads) InfoQ, others...</p> <p>This was really just an introduction.</p> <p>Bruce Williams</p> <p>bruce@codeuency.com</p> <p>twitter: wbruce</p>