SlideShare ist ein Scribd-Unternehmen logo
1 von 94
Downloaden Sie, um offline zu lesen
Ruby 1.9: It works!
    ihower@handlino.com
         2009/4/18
         OSDC.TW
Ruby 1.9: It (must) works!
       ihower@handlino.com
            2009/4/18
            OSDC.TW
?
•           a.k.a. ihower
•   http://ihower.idv.tw/blog/

•   http://twitter.com/ihower

•     2006                  Ruby
•       (    )      Rails Developer
•   http://handlino.com

•   http://registrano.com
Agenda
• Overview
• What’s changed?
• What’s New?
  (External Interater, M17N, The Threading Model)


• Ruby 1.9 on Rails
1. Overview
Ruby 1.8.6
• Ruby 1.8.6, release at 2007/3/12
• Stable
• Performance sucks
• Memory leaks
• NewRelic Report 69.4%
  http://railslab.newrelic.com/2009/04/01/the-state-of-the-stack-a-ruby-on-rails-benchmarking-report
Ruby 1.8.7

• Ruby 1.8.7 release at 2008/5/31
•               1.9
• gems, library            (   1.8.6   )


• JRuby 1.8.7
• NewRelic Report 14.5%
Ruby 1.9

• Ruby 1.9.0 release development version in
  2007/12/25
• Ruby 1.9.1 release stable/production version
  in 2009/1/30
• Better performance
• Better encoding support
Ruby Implementations
                           production

•   Ruby 1.8.6, 1.8.7 (MRI, Matz’ Ruby Interpreter)
    •   EngineYard                    1.8.6
        MBARI      GC patch      http://www.infoq.com/news/2009/01/ruby-patches-fix-leaks



•   Ruby 1.9.1 (YARV)
•    JRuby
    •     Ruby1.8.6         1.9


•    Ruby Enterprise Edition(REE)
    •       Ruby 1.8.6   GC     memory leak
Ruby Implementations
                   production


• MacRuby (based on Objective-C)
• Rubinius (Engine yard project)
• MagLev (based on smalltalk)
• IronRuby (based on Microsoft .NET)
• Cardinal (based on Parrot VM)
Performance                   (    1.8   2~2.5   )




http://antoniocangiano.com/category/ruby-benchmark-suite/
     http://github.com/acangiano/ruby-benchmark-suite/
Ubuntu : Intel® Q6600® quad-core
Computer Language Benchmarks Game

http://shootout.alioth.debian.org/
2. What’s changed?
Ordered Hash
{ :a => 1, :b=> 2, :c => 3 }.merge( :d => 4 )




     1.8   {:a=>1, :d=>4, :b=>2, :c=>3}



     1.9   {:a=>1, :b=>2, :c=>3, :d=>4}
new Hash literal

          config = { :foo => 1234, :bar => 6789 }
1.8,1.9


          Person.find(:all, :conditions => { :name => 'ihower' } )



          config = { foo: 1234, bar: 6789 }
1.9
          Person.find(:all, :conditions => { name: 'ihower' } )
Hash syntax
                                 =>


      {1,2,3,4}
1.8   => {1=>2, 3=>4}


      {1,2,3,4}
1.9
      => syntax error, unexpected ',', expecting tASSOC
Hash#select
hash = { :a => 1, :b => 2, :c => 3 }
hash.select{ |k, v| v > 1 }


           [[:b, 2], [:c, 3]]
     1.8


           {:b=>2, :c=>3}
     1.9
Array#to_s, Hash#to_s
 1.8                1.9

 [1,2,3,4].to_s     [1,2,3,4].to_s
 => quot;1234quot;          => quot;[1, 2, 3, 4]quot;

 {1=>2,3=>4}.to_s   {1=>2,3=>4}.to_s
 => quot;1234quot;          => quot;{1=>2, 3=>4}quot;
case syntax
name = case                        name = case
        when x == 1 : quot;onequot;                  when x == 1
 1.8    when x == 2 : quot;twoquot;                       quot;onequot;
                                    1.8,1.9
        else quot;manyquot;                          when x == 2
       end                                        quot;twoquot;
                                             else
                                                  quot;manyquot;
                                            end
name = case
          when x == 1 then quot;onequot;
          when x == 2 then quot;twoquot;
 1.8,1.9
          else quot;manyquot;
         end
block’s parameter always local
                             local

               x = quot;fooquot;
               y = quot;barquot;

               [1,2,3].each do |x|
                 y=x+1
               end



 1.8 [x,y] => [3, 4]       1.9 [x,y] => [quot;fooquot;, 4]
block’s parameter always local
                             local

               x = quot;fooquot;
               y = quot;barquot;

               [1,2,3].each do |x|
                 y=x+1
               end



 1.8 [x,y] => [3, 4]       1.9 [x,y] => [quot;fooquot;, 4]
block-local variable
                                                             local

                                                         bar = quot;ihowerquot;
                                                   1.9
          bar = quot;ihowerquot;
1.8,1.9


                                                         [1,2,3].each do |val; bar|
          [1,2,3].each do |val|
                                                          bar = val
           foo = val
                                                         end
           bar = val
          end
                                                         bar => quot;ihowerquot;
          foo   # NameError: undefined
                  local variable or method `foo’
          bar => 3
block-local variable
                                                             local

                                                         bar = quot;ihowerquot;
                                                   1.9
          bar = quot;ihowerquot;
1.8,1.9


                                                         [1,2,3].each do |val; bar|
          [1,2,3].each do |val|
                                                          bar = val
           foo = val
                                                         end
           bar = val
          end
                                                         bar => quot;ihowerquot;
          foo   # NameError: undefined
                  local variable or method `foo’
                                                                     bar
          bar => 3
block can accept block argrments

  proc1 = lambda do |a, *b, &block|
   pa
   pb
   pc
   block.call
  end

  proc1.call(1,2,3,4) { puts quot;in block1quot; }

  #
  1
  [2,3,4]
  quot;in block1quot;
new lambda literal
                  lambda

            lambda { |a| a*3 }.call(4)
  1.8,1.9
            # => 12


            lambda { |a| a*3 }[4]
  1.8,1.9
            # => 12


            ->(a) { a*3 }.(4)
   1.9      # => 12
def my_if(condition, then_clause, else_clause)
    if condition
        then_clause.call
    else
        else_clause.call
    end
end

5.times do |val|
    my_if (val < 3),
    -> { puts quot;#{val} is smallquot; },
    -> { puts quot;#{val} is bigquot; }
end

#
0   is   small
1   is   small
2   is   small
3   is   big
4   is   big
def my_while(cond, &body)
    while cond.call
        body.call
    end
end

a=0
my_while -> { a < 3 } do
    puts a
    a += 1
end

#
0
1
2
Kernel.proc
           , do not use it!


  • proc           lambda
1.8

  •
1.9 proc           Proc.new
BasicObject
                                             root


          Class.superclass.superclass => Object
1.8,1.9




1.8       Class.superclass.superclass.superclass => nil


          Class.superclass.superclass.superclass => BasicObject
1.9
          BasicObject.superclass => nil
          BasicObject.instance_methods
          => [:==, :equal?, :!, :!=, :instance_eval,   :instance_exec, :__send__]



                                                         metaprogramming
                                                          blank canvas
standard library changes
• + Rubygems
  •   no longer needed require ‘rubygems’


• + Rake
  •   no longer gem install rake


• ~ Test::Unit replaced by MiniTest
• - soap, jcode...etc, some rarely used, old
  libraries
3. What’s new?
External Iterator
Iterators
                                 to_enum

          Internal               External
                           1.9
1.8,1.9


arr = [ 1, 2, quot;ihowerquot; ]   arr = [ 1, 2, quot;ihowerquot; ]
arr.each do |a|            enum_a = arr.to_enum
    puts a                 #     Enumerators      (    each)
end
                           enum_a.next # => 1
# => 1                     enum_a.next # => 2
# => 2                     enum_a.next # => quot;ihowerquot;
# => quot;ihowerquot;
Enumerators
1.9                              1.9
                                 arr = [ 1, 2, quot;ihowerquot; ]
h = { foo: quot;567quot;, bar: quot;890quot; }
                                 enum_a =
enum_h = h.to_enum
                                 arr.to_enum(:each_with_index)
enum_h.next
# => [:foo, quot;567quot;]
                                 enum_a.next # => [1, 0]
enum_h.next
                                 enum_a.next # => [2, 1]
# => [:bar, quot;890quot;]
                                 enum_a.next # => [quot;ihowerquot;, 2]
StopIteration exception
1.9
      short_enum = [1, 2, 3].to_enum
      long_enum = ('a'..'z').to_enum

      loop do
          puts quot;#{short_enum.next} #{long_enum.next}quot;
      end

      # => 1-a
      # => 2-b
      # => 3-c
StopIteration exception
1.9
      short_enum = [1, 2, 3].to_enum
      long_enum = ('a'..'z').to_enum

      loop do
          puts quot;#{short_enum.next} #{long_enum.next}quot;
      end

      # => 1-a
                                   StopIteration
      # => 2-b
      # => 3-c
Enumerator from iterator
                          iterator method
1.9
      arr = [ 1, 2, quot;ihowerquot; ]
      enum_a = arr.each #                   Enumerator

      enum_a.next # => 1
      enum_a.next # => 2
      enum_a.next # => quot;ihowerquot;
Enumerators.new
              code block
1.9   seq = Enumerator.new do |yielder|
          n1 = 0
          n2 = 1
          loop do
              n3 = n1 + n2
              yielder.yield n3
              n1 = n2
              n2 = n3
          end
      end

      seq.next # 1
      seq.next # 2
      2.times { puts seq.next }
      #3
      #5
Enumerator objects are
    also enumerable
1.9
      seq.first(10)
      # => [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

      seq.to_a
      # Don’t do this if your Enumerator has infinite elements
M17N
(Multilingualization)
In Ruby 1.8, a String is always
   just a collection of bytes
Ruby 1.8 String fails
        >> quot;   quot;.reverse
  1.8
        => quot;207226 344quot;

        >> quot;   quot;.size
        => 6
Ruby 1.8 Regexp
                          UTF-8


• Support None (n or N), EUC (e or E),
  Shift_JIS (s or S), UTF-8 (u or U)

               >> quot;     quot;.scan(/./u)
     1.8,1.9


               => [quot;   quot;, quot; quot;]
Use Regexp to handle String
                    Regexp



          >> quot;   quot;.scan(/./u).reverse.join
1.8,1.9

          => quot;   quot;

          >> quot;   quot;.scan(/./u).size
          => 2
$KCODE = “U”
                      or ruby -KU

•    regular expressions            default encoding
• $KCODE = quot;Uquot;                    terminal
            >>   quot;   quot;
      1.8
            =>   quot;344270255346226207quot;
            >>   $KCODE='u'
            >>   quot;   quot;
            =>   quot;   quot;
Unicode codepoint
                 Ruby 1.8         UTF-8

          >> quot;   quot;.unpack(quot;U*quot;)
1.8,1.9
          => [20013, 25991]

          >> quot;   quot;.unpack(quot;U*quot;).reverse.pack(quot;U*quot;)
          => quot;   quot;

          >> quot;   quot;.unpack(quot;U*quot;).size
          => 2
Unicode codepoint(cont.)
              Rails ActiveSupport


           >> quot;   quot;.chars # in Rails
 1.8,1.9
           => #<ActiveSupport::Multibyte::Chars:0x25aebbc
           @wrapped_string=quot;   quot;>

           >> quot;   quot;.chars.size
           => 2
iconv library
                            UTF-8 data


•   C Library, it’s fast.

•   convert your encoding to UTF-8

•   handle it

•   export back to your encoding
jcode library
      too simple, not useful

        $KCODE = 'UTF8'
1.8
        require 'jcode'

        str = quot;   quot;
        str.size # 9
        str.jsize # 2
No enough encodings
           supported in Ruby 1.8
• String                Encoding
• Regexp
 •           encoding                          Regexp letter

 •                                       #String.upcase encoded data   valid?


• $KCODE
 •   String, IO object, program source
pick one encoding, likely Unicode, and works all data in one format? No.

Ruby 1.9 make it possible to work
  with data with 83 encoding.
>> Encoding.name_list

=> [quot;ASCII-8BITquot;, quot;UTF-8quot;, quot;US-ASCIIquot;, quot;Big5quot;, quot;CP949quot;, quot;Emacs-Mulequot;, quot;EUC-JPquot;,
quot;EUC-KRquot;, quot;EUC-TWquot;, quot;GB18030quot;, quot;GBKquot;, quot;ISO-8859-1quot;, quot;ISO-8859-2quot;, quot;ISO-8859-3quot;,
quot;ISO-8859-4quot;, quot;ISO-8859-5quot;, quot;ISO-8859-6quot;, quot;ISO-8859-7quot;, quot;ISO-8859-8quot;,
quot;ISO-8859-9quot;, quot;ISO-8859-10quot;, quot;ISO-8859-11quot;, quot;ISO-8859-13quot;, quot;ISO-8859-14quot;,
quot;ISO-8859-15quot;, quot;ISO-8859-16quot;, quot;KOI8-Rquot;, quot;KOI8-Uquot;, quot;Shift_JISquot;, quot;UTF-16BEquot;,
quot;UTF-16LEquot;, quot;UTF-32BEquot;, quot;UTF-32LEquot;, quot;Windows-1251quot;, quot;BINARYquot;, quot;IBM437quot;,
quot;CP437quot;, quot;IBM737quot;, quot;CP737quot;, quot;IBM775quot;, quot;CP775quot;, quot;CP850quot;, quot;IBM850quot;, quot;IBM852quot;,
quot;CP852quot;, quot;IBM855quot;, quot;CP855quot;, quot;IBM857quot;, quot;CP857quot;, quot;IBM860quot;, quot;CP860quot;, quot;IBM861quot;,
quot;CP861quot;, quot;IBM862quot;, quot;CP862quot;, quot;IBM863quot;, quot;CP863quot;, quot;IBM864quot;, quot;CP864quot;, quot;IBM865quot;,
quot;CP865quot;, quot;IBM866quot;, quot;CP866quot;, quot;IBM869quot;, quot;CP869quot;, quot;Windows-1258quot;, quot;CP1258quot;,
quot;GB1988quot;, quot;macCentEuroquot;, quot;macCroatianquot;, quot;macCyrillicquot;, quot;macGreekquot;,
quot;macIcelandquot;, quot;macRomanquot;, quot;macRomaniaquot;, quot;macThaiquot;, quot;macTurkishquot;, quot;macUkrainequot;,
quot;CP950quot;, quot;stateless-ISO-2022-JPquot;, quot;eucJPquot;, quot;eucJP-msquot;, quot;euc-jp-msquot;, quot;CP51932quot;,
quot;eucKRquot;, quot;eucTWquot;, quot;GB2312quot;, quot;EUC-CNquot;, quot;eucCNquot;, quot;GB12345quot;, quot;CP936quot;, quot;ISO-2022-
JPquot;, quot;ISO2022-JPquot;, quot;ISO-2022-JP-2quot;, quot;ISO2022-JP2quot;, quot;ISO8859-1quot;, quot;Windows-1252quot;,
quot;CP1252quot;, quot;ISO8859-2quot;, quot;Windows-1250quot;, quot;CP1250quot;, quot;ISO8859-3quot;, quot;ISO8859-4quot;,
quot;ISO8859-5quot;, quot;ISO8859-6quot;, quot;Windows-1256quot;, quot;CP1256quot;, quot;ISO8859-7quot;,
quot;Windows-1253quot;, quot;CP1253quot;, quot;ISO8859-8quot;, quot;Windows-1255quot;, quot;CP1255quot;, quot;ISO8859-9quot;,
quot;Windows-1254quot;, quot;CP1254quot;, quot;ISO8859-10quot;, quot;ISO8859-11quot;, quot;TIS-620quot;, quot;Windows-874quot;,
quot;CP874quot;, quot;ISO8859-13quot;, quot;Windows-1257quot;, quot;CP1257quot;, quot;ISO8859-14quot;, quot;ISO8859-15quot;,
quot;ISO8859-16quot;, quot;CP878quot;, quot;SJISquot;, quot;Windows-31Jquot;, quot;CP932quot;, quot;csWindows31Jquot;,
quot;MacJapanesequot;, quot;MacJapanquot;, quot;ASCIIquot;, quot;ANSI_X3.4-1968quot;, quot;646quot;, quot;UTF-7quot;,
quot;CP65000quot;, quot;CP65001quot;, quot;UTF8-MACquot;, quot;UTF-8-MACquot;, quot;UCS-2BEquot;, quot;UCS-4BEquot;, quot;UCS-4LEquot;,
quot;CP1251quot;, quot;localequot;, quot;externalquot;, quot;internalquot;]
All String are Encoded
• In Ruby 1.9 a String is a collection of
  encoded characters.
           raw bytes     Encoding

            >> quot;   quot;.encoding.name
     1.9
            => quot;UTF-8quot;
                               Encoding
                                 object
String works in characters
       1.9   >> quot;   quot;.reverse
             => quot;   quot;

             >> quot;   quot;.size
             => 2

             >> quot;   quot;.bytesize
             => 6
String Indexing
                    1.9
1.8
      >> quot;abcquot;[0]     >> quot;abcquot;[0]
      => 97           => quot;aquot;

      >> quot;   quot;[1]     >> quot;       quot;[1]
      => 184          => quot;   quot;

                      >> quot;abcquot;[0].ord
                      => 97
!

In Ruby 1.9, String has attached
 Encoding object, and works in
          characters.
Transcoding
      utf8 = quot;   quot;
1.9
      utf8.bytesize # 6
      utf8.bytes.to_a # [230, 184, 172, 232, 169, 166]

      big5 = utf8.encode(quot;big5quot;)

      big5.encoding.name # ”Big5”
      big5.bytesize # 4
      big5.bytes.to_a # [180, 250, 184, 213]
Transcoding fails
      str = quot;Résuméquot;
1.9   str.encode(quot;big5quot;)

      => Encoding::UndefinedConversionError: quot;xC3xA9quot;
      from UTF-8 to Big5
      	 from (irb):2:in `encode'
      	 from (irb):2
      	 from /usr/local/bin/irb19:12:in `<main>'
Force Transcoding
                          byte data

      utf8 = quot;   quot;
1.9
      big5 = utf8.encode(quot;big5quot;)
      big5.valid_encoding?
      => true

      big5.force_encoding(quot;utf-8quot;)
      big5.valid_encoding?
      => false
Force Transcoding fails
      big5.valid_encoding? # false
1.9   big5 =~ /123456/

      => ArgumentError: invalid byte sequence in UTF-8
      	 from (irb):11
      	 from /usr/local/bin/irb19:12:in `<main>'
Encoding.compatible?
                : ASCII with a bigger Encoding

       ascii = quot;my quot;.force_encoding(quot;asciiquot;)
1.9
       utf8 = quot;Résuméquot;

       #
       Encoding.compatible?(ascii, utf8)
       #<Encoding:UTF-8>

       #
       my_resume = ascii + utf8
       puts my_resume                 # quot;My Résuméquot;
       puts my_resume.encoding.name   # UTF-8
Encoding.compatible?
      big5 = quot;   quot;.encode(quot;big5quot;)
1.9
      utf8 = quot;Résuméquot;

      #
      Encoding.compatible?(big5, utf8)   # nil

      #
      big5 + utf8

      => Encoding::CompatibilityError: incompatible character
      encodings: Big5 and UTF-8
      	 from (irb):25
      	 from /usr/local/bin/irb19:12:in `<main>'
String Iteration
               each

 • Strings are no longer enumerable
 • Ruby 1.8 each() has been removed
 •
1.9 Ruby 1.9 use explicit iterator

    • each_line
    • each_byte
    • each_char
    • each_codepoint
What’s default encoding?
       ?   encoding   ?
program source encoding
                magic comment

    # encoding: UTF-8

    #!/usr/bin/env ruby -w
    # encoding: UTF-8

    # coding: UTF-8

    # -*- coding: UTF-8 -*-
program without magic comment

ruby foobar.rb # US-ASCII

ruby -e foobar.rb     irb #   OS   ($LC_CTYPE, $LANG)


ruby -KU foobar.rb # UTF-8
program source
      encoding           error

invalid multibyte char (US-ASCII)
IO Object
1.9
      # encoding: utf-8
      f = File.open(quot;big5.txtquot;,quot;r:big5quot;)
      puts f.external_encoding # Big5
      puts f.gets.encoding # Big5
IO Object
1.9
      # encoding: utf-8
      f = File.open(quot;big5.txtquot;,quot;r:big5:utf-8quot;)
      puts f.external_encoding # Big5
      puts f.internal_encoding # UTF-8
      puts f.gets.encoding # UTF-8
IO Object
1.9
      # encoding: utf-8
      f = File.open(quot;another_big5.txtquot;, quot;w:big5quot;)
      puts f.external_encoding # Big5
      data = quot;     quot;
      puts data.encoding.name # UTF-8
      f << data
IO Object
1.9
      # encoding: utf-8
      f = File.open(quot;another_big5.txtquot;, quot;w:big5quot;)
      puts f.external_encoding # Big5
      data = quot;     quot;
      puts data.encoding.name # UTF-8
      f << data
Regexp has encoding too
                          • Oniguruma engine
1.9
                            http://www.geocities.jp/kosako3/oniguruma/
/w/.encoding

                          • Same basic API
=> #<Encoding:US-ASCII>


                          • better performance
/   /.encoding
=> #<Encoding:UTF-8>

                          • support for a lot of encoding
                          • extended syntax
Default Encoding Overview

• String literal program source
• Symbols Regexp                             7-bit
  US-ASCII                          program source
• IO             external_encoding           OS
 •     ruby -E

 •     Encoding.external_encoding
The Threading model
Fibers
    (semi-coroutine)
           code block
f = Fiber.new {
1.9
          2.times do
              puts quot;Fiber say hiquot;
              Fiber.yield #
              puts quot;Fiber say byequot;
          end
      }#

      >>   f.resume
      #       Fiber say hi
      >>   f.resume
      #        Fiber say bye
      #        Fiber say hi
      >>   f.resume
      #        Fiber say bye
      >>   f.resume
       FiberError: dead fiber called
      	 from (irb):78:in `resume'
      	 from (irb):78
      	 from /usr/local/bin/irb19:12:in `<main>'
Fibers
•        Enumerator
•        fiber library                                  fiber
    object
• (Ruby 1.8             continuation
               continuation        kernel   library)

•                        ... zzz
Native Threads
 • Green threads
1.8
       Ruby thread          native thread

 • Native (operation system) thread
1.9
       Ruby thread       native thread
GIL
                Giant Interpreter Lock


 •
1.9
                 C extension libraries
      thread safe
           Thread
      (                     Ruby Threads   JRuby)
4. Ruby on Rails
Ruby 1.9 on Rails

• Rails 2.3.2 or edge
• mysql-ruby driver for Ruby 1.9
• Passenger(mod_rails) or Thin
Upgrade issue
• program source encoding problem
 •   invalid multibyte char                                    # encoding: UTF-8


• encoding compatibility problem
 •                                  ACSII-8BIT (binary)          UTF-8 String

 •   http://github.com/hectoregm/mysql-ruby (UTF-8 friendly)


• some gem, plugins are not Ruby 1.9 compatible
 •   http://isitruby19.com/
Benchmark

• Rails 2.3.2 production mode
• No DB, just render :text => 'hello'
• My MacBook Pro 2.2G
• httperf
Performance
              Reply rate [replies/s]

              min       avg            max   stddev
Ruby 1.8.6   241.8     258.3       267.4      14.4
 Mongrel
  1.1.5
Ruby 1.8.6   244.6     260.9       271.2      11.4
mod_rails
Ruby 1.9.1   264.0     269.5       273.4      4.9
mod_rails
Ruby 1.8.6   244.5     273.2       299.6      22.7
Thin 1.0.0
Ruby 1.9.1   348.4     363.2       371.2      12.8
Thin 1.0.0
Performance
Ruby 1.9                            Rails Stack                   !!

 400

 300
                                             Ruby 1.8.6/Mongrel 1.1.5
                                             Ruby 1.8.6/mod_rails edge
 200                                         Ruby 1.9.1/mod_rails edge
                                             Ruby 1.8.6/Thin 1.0.0
                                             Ruby 1.9.1/Thin 1.0.0
 100

   0
           Reply rate [replies/s]
Performance
Ruby 1.9                            Rails Stack                   !!

 400

 300
                                             Ruby 1.8.6/Mongrel 1.1.5
                                             Ruby 1.8.6/mod_rails edge
 200                                         Ruby 1.9.1/mod_rails edge
                                             Ruby 1.8.6/Thin 1.0.0
                                             Ruby 1.9.1/Thin 1.0.0
 100

   0
           Reply rate [replies/s]
5. Conclusion
TIOBE Programming Community Index for April 2009
Ruby challenge
• Ruby 1.9 change a lot and 1.8 is slow and
  should be deprecated.
• Migrate to Ruby 1.9 is the big challenge
  in 2009.
Reference
•   Understanding M17n
    http://blog.grayproductions.net/articles/understanding_m17n


•   Books
    •     Programming Ruby 1.9 (Pragmatic)
    •     The Ruby Programming Language (O’Reilly)
    •     Ruby Best Practices (O’Reilly)
    •     The Well-Grounded Rubyist (Manning)
•   Slide
    •     MigrationToRuby 1.9
    •     Ruby 1.9: What to Expect
          http://slideshow.rubyforge.org/ruby19.html
    •     Matz on Ruby 1.9
Other reference links
•   http://svn.ruby-lang.org/repos/ruby/tags/v1_9_1_0/NEWS

•   http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed

•   http://blog.grayproductions.net/articles/getting_code_ready_for_ruby_19

•   http://dablog.rubypal.com/2009/1/14/10-things-to-be-aware-of-in-moving-to-
    ruby-1-9

•   http://dablog.rubypal.com/2009/1/16/son-of-10-things-to-be-aware-of-in-
    ruby-1-9

•   http://blog.kineticweb.com/articles/2009/01/30/ruby-1-9-1-the-other-features
Thank you.
Bonus
Object#tap
puts quot;dogquot;.reverse
          .tap{ |o| puts quot;reversed: #{o}quot; }
          .upcase

#
reversed: god
GOD

Más contenido relacionado

Was ist angesagt?

Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdRicardo Signes
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012Christopher Spring
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worldsChristopher Spring
 
Exploit techniques - a quick review
Exploit techniques - a quick reviewExploit techniques - a quick review
Exploit techniques - a quick reviewCe.Se.N.A. Security
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegeninovex GmbH
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8Dhaval Dalal
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Dhaval Dalal
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!José Paumard
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharpDhaval Dalal
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with GoNaoki AINOYA
 
Exploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your pluginsExploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your pluginsMarian Marinov
 
Writing Redis in Python with asyncio
Writing Redis in Python with asyncioWriting Redis in Python with asyncio
Writing Redis in Python with asyncioJames Saryerwinnie
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is hereSebastiano Armeli
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overviewhesher
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6Solution4Future
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 

Was ist angesagt? (20)

Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::Cmd
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
Exploit techniques - a quick review
Exploit techniques - a quick reviewExploit techniques - a quick review
Exploit techniques - a quick review
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegen
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
C++ L08-Classes Part1
C++ L08-Classes Part1C++ L08-Classes Part1
C++ L08-Classes Part1
 
Mona cheatsheet
Mona cheatsheetMona cheatsheet
Mona cheatsheet
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharp
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
 
Exploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your pluginsExploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your plugins
 
Writing Redis in Python with asyncio
Writing Redis in Python with asyncioWriting Redis in Python with asyncio
Writing Redis in Python with asyncio
 
Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 

Andere mochten auch

Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On RailsWen-Tien Chang
 
那些 Functional Programming 教我的事
那些 Functional Programming 教我的事那些 Functional Programming 教我的事
那些 Functional Programming 教我的事Wen-Tien Chang
 
MacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMatt Aimonetti
 
Boost your productivity!: Productivity tips for rails developers - Lightning ...
Boost your productivity!: Productivity tips for rails developers - Lightning ...Boost your productivity!: Productivity tips for rails developers - Lightning ...
Boost your productivity!: Productivity tips for rails developers - Lightning ...Alberto Perdomo
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upWen-Tien Chang
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Wen-Tien Chang
 
Ruby vs Java
Ruby vs JavaRuby vs Java
Ruby vs JavaBelighted
 
Ruby For Java Programmers
Ruby For Java ProgrammersRuby For Java Programmers
Ruby For Java ProgrammersMike Bowler
 
淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2Wen-Tien Chang
 
10 Ruby and Rails Pro Tips
10 Ruby and Rails Pro Tips10 Ruby and Rails Pro Tips
10 Ruby and Rails Pro TipsMichel Pigassou
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails IntroductionThomas Fuchs
 
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習台灣資料科學年會
 
TEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of WorkTEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of WorkVolker Hirsch
 

Andere mochten auch (18)

Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On Rails
 
Scala vs Ruby
Scala vs RubyScala vs Ruby
Scala vs Ruby
 
那些 Functional Programming 教我的事
那些 Functional Programming 教我的事那些 Functional Programming 教我的事
那些 Functional Programming 教我的事
 
MacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meet
 
RESTful Rails2
RESTful Rails2RESTful Rails2
RESTful Rails2
 
Boost your productivity!: Productivity tips for rails developers - Lightning ...
Boost your productivity!: Productivity tips for rails developers - Lightning ...Boost your productivity!: Productivity tips for rails developers - Lightning ...
Boost your productivity!: Productivity tips for rails developers - Lightning ...
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom up
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best Practices
 
Ruby vs Java
Ruby vs JavaRuby vs Java
Ruby vs Java
 
Ruby For Java Programmers
Ruby For Java ProgrammersRuby For Java Programmers
Ruby For Java Programmers
 
Ruby everywhere
Ruby everywhereRuby everywhere
Ruby everywhere
 
Ruby on Rails for beginners
Ruby on Rails for beginnersRuby on Rails for beginners
Ruby on Rails for beginners
 
淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2
 
10 Ruby and Rails Pro Tips
10 Ruby and Rails Pro Tips10 Ruby and Rails Pro Tips
10 Ruby and Rails Pro Tips
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails Introduction
 
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
 
TEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of WorkTEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of Work
 

Ähnlich wie Ruby 1.9

Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02Apoorvi Kapoor
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9tomaspavelka
 
Ruby 程式語言簡介
Ruby 程式語言簡介Ruby 程式語言簡介
Ruby 程式語言簡介Wen-Tien Chang
 
Impacta - Show Day de Rails
Impacta - Show Day de RailsImpacta - Show Day de Rails
Impacta - Show Day de RailsFabio Akita
 
Ruby 1.9 Introduction
Ruby 1.9 IntroductionRuby 1.9 Introduction
Ruby 1.9 IntroductionBradly Feeley
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Introduction to Erlang
Introduction to ErlangIntroduction to Erlang
Introduction to ErlangGabriele Lana
 
A Toda Maquina Con Ruby on Rails
A Toda Maquina Con Ruby on RailsA Toda Maquina Con Ruby on Rails
A Toda Maquina Con Ruby on RailsRafael García
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Railselliando dias
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 
Interface de Voz con Rails
Interface de Voz con RailsInterface de Voz con Rails
Interface de Voz con RailsSvet Ivantchev
 
Out with Regex, In with Tokens
Out with Regex, In with TokensOut with Regex, In with Tokens
Out with Regex, In with Tokensscoates
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Raffi Krikorian
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 

Ähnlich wie Ruby 1.9 (20)

Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02Ruby19 osdc-090418222718-phpapp02
Ruby19 osdc-090418222718-phpapp02
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9
 
Ruby 程式語言簡介
Ruby 程式語言簡介Ruby 程式語言簡介
Ruby 程式語言簡介
 
Impacta - Show Day de Rails
Impacta - Show Day de RailsImpacta - Show Day de Rails
Impacta - Show Day de Rails
 
Ruby 1.9 Introduction
Ruby 1.9 IntroductionRuby 1.9 Introduction
Ruby 1.9 Introduction
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Introduction to Erlang
Introduction to ErlangIntroduction to Erlang
Introduction to Erlang
 
A Toda Maquina Con Ruby on Rails
A Toda Maquina Con Ruby on RailsA Toda Maquina Con Ruby on Rails
A Toda Maquina Con Ruby on Rails
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Interface de Voz con Rails
Interface de Voz con RailsInterface de Voz con Rails
Interface de Voz con Rails
 
Out with Regex, In with Tokens
Out with Regex, In with TokensOut with Regex, In with Tokens
Out with Regex, In with Tokens
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
 

Mehr von Wen-Tien Chang

⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨Wen-Tien Chang
 
Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Wen-Tien Chang
 
A brief introduction to Machine Learning
A brief introduction to Machine LearningA brief introduction to Machine Learning
A brief introduction to Machine LearningWen-Tien Chang
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails TutorialWen-Tien Chang
 
ALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateWen-Tien Chang
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Wen-Tien Chang
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyWen-Tien Chang
 
從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事Wen-Tien Chang
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩Wen-Tien Chang
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Wen-Tien Chang
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0Wen-Tien Chang
 
RubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingRubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingWen-Tien Chang
 
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean StartupWen-Tien Chang
 
RubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingRubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingWen-Tien Chang
 
BDD style Unit Testing
BDD style Unit TestingBDD style Unit Testing
BDD style Unit TestingWen-Tien Chang
 
RSpec 讓你愛上寫測試
RSpec 讓你愛上寫測試RSpec 讓你愛上寫測試
RSpec 讓你愛上寫測試Wen-Tien Chang
 
Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3Wen-Tien Chang
 

Mehr von Wen-Tien Chang (20)

⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨
 
Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛
 
A brief introduction to Machine Learning
A brief introduction to Machine LearningA brief introduction to Machine Learning
A brief introduction to Machine Learning
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails Tutorial
 
RSpec & TDD Tutorial
RSpec & TDD TutorialRSpec & TDD Tutorial
RSpec & TDD Tutorial
 
ALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborate
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in Ruby
 
從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0
 
RubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingRubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & Closing
 
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
 
Git Tutorial 教學
Git Tutorial 教學Git Tutorial 教學
Git Tutorial 教學
 
RubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingRubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & Closing
 
BDD style Unit Testing
BDD style Unit TestingBDD style Unit Testing
BDD style Unit Testing
 
RSpec 讓你愛上寫測試
RSpec 讓你愛上寫測試RSpec 讓你愛上寫測試
RSpec 讓你愛上寫測試
 
Git and Github
Git and GithubGit and Github
Git and Github
 
Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3
 

Ruby 1.9

  • 1. Ruby 1.9: It works! ihower@handlino.com 2009/4/18 OSDC.TW
  • 2. Ruby 1.9: It (must) works! ihower@handlino.com 2009/4/18 OSDC.TW
  • 3. ? • a.k.a. ihower • http://ihower.idv.tw/blog/ • http://twitter.com/ihower • 2006 Ruby • ( ) Rails Developer • http://handlino.com • http://registrano.com
  • 4. Agenda • Overview • What’s changed? • What’s New? (External Interater, M17N, The Threading Model) • Ruby 1.9 on Rails
  • 6. Ruby 1.8.6 • Ruby 1.8.6, release at 2007/3/12 • Stable • Performance sucks • Memory leaks • NewRelic Report 69.4% http://railslab.newrelic.com/2009/04/01/the-state-of-the-stack-a-ruby-on-rails-benchmarking-report
  • 7. Ruby 1.8.7 • Ruby 1.8.7 release at 2008/5/31 • 1.9 • gems, library ( 1.8.6 ) • JRuby 1.8.7 • NewRelic Report 14.5%
  • 8. Ruby 1.9 • Ruby 1.9.0 release development version in 2007/12/25 • Ruby 1.9.1 release stable/production version in 2009/1/30 • Better performance • Better encoding support
  • 9. Ruby Implementations production • Ruby 1.8.6, 1.8.7 (MRI, Matz’ Ruby Interpreter) • EngineYard 1.8.6 MBARI GC patch http://www.infoq.com/news/2009/01/ruby-patches-fix-leaks • Ruby 1.9.1 (YARV) • JRuby • Ruby1.8.6 1.9 • Ruby Enterprise Edition(REE) • Ruby 1.8.6 GC memory leak
  • 10. Ruby Implementations production • MacRuby (based on Objective-C) • Rubinius (Engine yard project) • MagLev (based on smalltalk) • IronRuby (based on Microsoft .NET) • Cardinal (based on Parrot VM)
  • 11. Performance ( 1.8 2~2.5 ) http://antoniocangiano.com/category/ruby-benchmark-suite/ http://github.com/acangiano/ruby-benchmark-suite/
  • 12. Ubuntu : Intel® Q6600® quad-core Computer Language Benchmarks Game http://shootout.alioth.debian.org/
  • 14. Ordered Hash { :a => 1, :b=> 2, :c => 3 }.merge( :d => 4 ) 1.8 {:a=>1, :d=>4, :b=>2, :c=>3} 1.9 {:a=>1, :b=>2, :c=>3, :d=>4}
  • 15. new Hash literal config = { :foo => 1234, :bar => 6789 } 1.8,1.9 Person.find(:all, :conditions => { :name => 'ihower' } ) config = { foo: 1234, bar: 6789 } 1.9 Person.find(:all, :conditions => { name: 'ihower' } )
  • 16. Hash syntax => {1,2,3,4} 1.8 => {1=>2, 3=>4} {1,2,3,4} 1.9 => syntax error, unexpected ',', expecting tASSOC
  • 17. Hash#select hash = { :a => 1, :b => 2, :c => 3 } hash.select{ |k, v| v > 1 } [[:b, 2], [:c, 3]] 1.8 {:b=>2, :c=>3} 1.9
  • 18. Array#to_s, Hash#to_s 1.8 1.9 [1,2,3,4].to_s [1,2,3,4].to_s => quot;1234quot; => quot;[1, 2, 3, 4]quot; {1=>2,3=>4}.to_s {1=>2,3=>4}.to_s => quot;1234quot; => quot;{1=>2, 3=>4}quot;
  • 19. case syntax name = case name = case when x == 1 : quot;onequot; when x == 1 1.8 when x == 2 : quot;twoquot; quot;onequot; 1.8,1.9 else quot;manyquot; when x == 2 end quot;twoquot; else quot;manyquot; end name = case when x == 1 then quot;onequot; when x == 2 then quot;twoquot; 1.8,1.9 else quot;manyquot; end
  • 20. block’s parameter always local local x = quot;fooquot; y = quot;barquot; [1,2,3].each do |x| y=x+1 end 1.8 [x,y] => [3, 4] 1.9 [x,y] => [quot;fooquot;, 4]
  • 21. block’s parameter always local local x = quot;fooquot; y = quot;barquot; [1,2,3].each do |x| y=x+1 end 1.8 [x,y] => [3, 4] 1.9 [x,y] => [quot;fooquot;, 4]
  • 22. block-local variable local bar = quot;ihowerquot; 1.9 bar = quot;ihowerquot; 1.8,1.9 [1,2,3].each do |val; bar| [1,2,3].each do |val| bar = val foo = val end bar = val end bar => quot;ihowerquot; foo # NameError: undefined local variable or method `foo’ bar => 3
  • 23. block-local variable local bar = quot;ihowerquot; 1.9 bar = quot;ihowerquot; 1.8,1.9 [1,2,3].each do |val; bar| [1,2,3].each do |val| bar = val foo = val end bar = val end bar => quot;ihowerquot; foo # NameError: undefined local variable or method `foo’ bar bar => 3
  • 24. block can accept block argrments proc1 = lambda do |a, *b, &block| pa pb pc block.call end proc1.call(1,2,3,4) { puts quot;in block1quot; } # 1 [2,3,4] quot;in block1quot;
  • 25. new lambda literal lambda lambda { |a| a*3 }.call(4) 1.8,1.9 # => 12 lambda { |a| a*3 }[4] 1.8,1.9 # => 12 ->(a) { a*3 }.(4) 1.9 # => 12
  • 26. def my_if(condition, then_clause, else_clause) if condition then_clause.call else else_clause.call end end 5.times do |val| my_if (val < 3), -> { puts quot;#{val} is smallquot; }, -> { puts quot;#{val} is bigquot; } end # 0 is small 1 is small 2 is small 3 is big 4 is big
  • 27. def my_while(cond, &body) while cond.call body.call end end a=0 my_while -> { a < 3 } do puts a a += 1 end # 0 1 2
  • 28. Kernel.proc , do not use it! • proc lambda 1.8 • 1.9 proc Proc.new
  • 29. BasicObject root Class.superclass.superclass => Object 1.8,1.9 1.8 Class.superclass.superclass.superclass => nil Class.superclass.superclass.superclass => BasicObject 1.9 BasicObject.superclass => nil BasicObject.instance_methods => [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__] metaprogramming blank canvas
  • 30. standard library changes • + Rubygems • no longer needed require ‘rubygems’ • + Rake • no longer gem install rake • ~ Test::Unit replaced by MiniTest • - soap, jcode...etc, some rarely used, old libraries
  • 33. Iterators to_enum Internal External 1.9 1.8,1.9 arr = [ 1, 2, quot;ihowerquot; ] arr = [ 1, 2, quot;ihowerquot; ] arr.each do |a| enum_a = arr.to_enum puts a # Enumerators ( each) end enum_a.next # => 1 # => 1 enum_a.next # => 2 # => 2 enum_a.next # => quot;ihowerquot; # => quot;ihowerquot;
  • 34. Enumerators 1.9 1.9 arr = [ 1, 2, quot;ihowerquot; ] h = { foo: quot;567quot;, bar: quot;890quot; } enum_a = enum_h = h.to_enum arr.to_enum(:each_with_index) enum_h.next # => [:foo, quot;567quot;] enum_a.next # => [1, 0] enum_h.next enum_a.next # => [2, 1] # => [:bar, quot;890quot;] enum_a.next # => [quot;ihowerquot;, 2]
  • 35. StopIteration exception 1.9 short_enum = [1, 2, 3].to_enum long_enum = ('a'..'z').to_enum loop do puts quot;#{short_enum.next} #{long_enum.next}quot; end # => 1-a # => 2-b # => 3-c
  • 36. StopIteration exception 1.9 short_enum = [1, 2, 3].to_enum long_enum = ('a'..'z').to_enum loop do puts quot;#{short_enum.next} #{long_enum.next}quot; end # => 1-a StopIteration # => 2-b # => 3-c
  • 37. Enumerator from iterator iterator method 1.9 arr = [ 1, 2, quot;ihowerquot; ] enum_a = arr.each # Enumerator enum_a.next # => 1 enum_a.next # => 2 enum_a.next # => quot;ihowerquot;
  • 38. Enumerators.new code block 1.9 seq = Enumerator.new do |yielder| n1 = 0 n2 = 1 loop do n3 = n1 + n2 yielder.yield n3 n1 = n2 n2 = n3 end end seq.next # 1 seq.next # 2 2.times { puts seq.next } #3 #5
  • 39. Enumerator objects are also enumerable 1.9 seq.first(10) # => [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] seq.to_a # Don’t do this if your Enumerator has infinite elements
  • 41. In Ruby 1.8, a String is always just a collection of bytes
  • 42. Ruby 1.8 String fails >> quot; quot;.reverse 1.8 => quot;207226 344quot; >> quot; quot;.size => 6
  • 43. Ruby 1.8 Regexp UTF-8 • Support None (n or N), EUC (e or E), Shift_JIS (s or S), UTF-8 (u or U) >> quot; quot;.scan(/./u) 1.8,1.9 => [quot; quot;, quot; quot;]
  • 44. Use Regexp to handle String Regexp >> quot; quot;.scan(/./u).reverse.join 1.8,1.9 => quot; quot; >> quot; quot;.scan(/./u).size => 2
  • 45. $KCODE = “U” or ruby -KU • regular expressions default encoding • $KCODE = quot;Uquot; terminal >> quot; quot; 1.8 => quot;344270255346226207quot; >> $KCODE='u' >> quot; quot; => quot; quot;
  • 46. Unicode codepoint Ruby 1.8 UTF-8 >> quot; quot;.unpack(quot;U*quot;) 1.8,1.9 => [20013, 25991] >> quot; quot;.unpack(quot;U*quot;).reverse.pack(quot;U*quot;) => quot; quot; >> quot; quot;.unpack(quot;U*quot;).size => 2
  • 47. Unicode codepoint(cont.) Rails ActiveSupport >> quot; quot;.chars # in Rails 1.8,1.9 => #<ActiveSupport::Multibyte::Chars:0x25aebbc @wrapped_string=quot; quot;> >> quot; quot;.chars.size => 2
  • 48. iconv library UTF-8 data • C Library, it’s fast. • convert your encoding to UTF-8 • handle it • export back to your encoding
  • 49. jcode library too simple, not useful $KCODE = 'UTF8' 1.8 require 'jcode' str = quot; quot; str.size # 9 str.jsize # 2
  • 50. No enough encodings supported in Ruby 1.8 • String Encoding • Regexp • encoding Regexp letter • #String.upcase encoded data valid? • $KCODE • String, IO object, program source
  • 51. pick one encoding, likely Unicode, and works all data in one format? No. Ruby 1.9 make it possible to work with data with 83 encoding.
  • 52. >> Encoding.name_list => [quot;ASCII-8BITquot;, quot;UTF-8quot;, quot;US-ASCIIquot;, quot;Big5quot;, quot;CP949quot;, quot;Emacs-Mulequot;, quot;EUC-JPquot;, quot;EUC-KRquot;, quot;EUC-TWquot;, quot;GB18030quot;, quot;GBKquot;, quot;ISO-8859-1quot;, quot;ISO-8859-2quot;, quot;ISO-8859-3quot;, quot;ISO-8859-4quot;, quot;ISO-8859-5quot;, quot;ISO-8859-6quot;, quot;ISO-8859-7quot;, quot;ISO-8859-8quot;, quot;ISO-8859-9quot;, quot;ISO-8859-10quot;, quot;ISO-8859-11quot;, quot;ISO-8859-13quot;, quot;ISO-8859-14quot;, quot;ISO-8859-15quot;, quot;ISO-8859-16quot;, quot;KOI8-Rquot;, quot;KOI8-Uquot;, quot;Shift_JISquot;, quot;UTF-16BEquot;, quot;UTF-16LEquot;, quot;UTF-32BEquot;, quot;UTF-32LEquot;, quot;Windows-1251quot;, quot;BINARYquot;, quot;IBM437quot;, quot;CP437quot;, quot;IBM737quot;, quot;CP737quot;, quot;IBM775quot;, quot;CP775quot;, quot;CP850quot;, quot;IBM850quot;, quot;IBM852quot;, quot;CP852quot;, quot;IBM855quot;, quot;CP855quot;, quot;IBM857quot;, quot;CP857quot;, quot;IBM860quot;, quot;CP860quot;, quot;IBM861quot;, quot;CP861quot;, quot;IBM862quot;, quot;CP862quot;, quot;IBM863quot;, quot;CP863quot;, quot;IBM864quot;, quot;CP864quot;, quot;IBM865quot;, quot;CP865quot;, quot;IBM866quot;, quot;CP866quot;, quot;IBM869quot;, quot;CP869quot;, quot;Windows-1258quot;, quot;CP1258quot;, quot;GB1988quot;, quot;macCentEuroquot;, quot;macCroatianquot;, quot;macCyrillicquot;, quot;macGreekquot;, quot;macIcelandquot;, quot;macRomanquot;, quot;macRomaniaquot;, quot;macThaiquot;, quot;macTurkishquot;, quot;macUkrainequot;, quot;CP950quot;, quot;stateless-ISO-2022-JPquot;, quot;eucJPquot;, quot;eucJP-msquot;, quot;euc-jp-msquot;, quot;CP51932quot;, quot;eucKRquot;, quot;eucTWquot;, quot;GB2312quot;, quot;EUC-CNquot;, quot;eucCNquot;, quot;GB12345quot;, quot;CP936quot;, quot;ISO-2022- JPquot;, quot;ISO2022-JPquot;, quot;ISO-2022-JP-2quot;, quot;ISO2022-JP2quot;, quot;ISO8859-1quot;, quot;Windows-1252quot;, quot;CP1252quot;, quot;ISO8859-2quot;, quot;Windows-1250quot;, quot;CP1250quot;, quot;ISO8859-3quot;, quot;ISO8859-4quot;, quot;ISO8859-5quot;, quot;ISO8859-6quot;, quot;Windows-1256quot;, quot;CP1256quot;, quot;ISO8859-7quot;, quot;Windows-1253quot;, quot;CP1253quot;, quot;ISO8859-8quot;, quot;Windows-1255quot;, quot;CP1255quot;, quot;ISO8859-9quot;, quot;Windows-1254quot;, quot;CP1254quot;, quot;ISO8859-10quot;, quot;ISO8859-11quot;, quot;TIS-620quot;, quot;Windows-874quot;, quot;CP874quot;, quot;ISO8859-13quot;, quot;Windows-1257quot;, quot;CP1257quot;, quot;ISO8859-14quot;, quot;ISO8859-15quot;, quot;ISO8859-16quot;, quot;CP878quot;, quot;SJISquot;, quot;Windows-31Jquot;, quot;CP932quot;, quot;csWindows31Jquot;, quot;MacJapanesequot;, quot;MacJapanquot;, quot;ASCIIquot;, quot;ANSI_X3.4-1968quot;, quot;646quot;, quot;UTF-7quot;, quot;CP65000quot;, quot;CP65001quot;, quot;UTF8-MACquot;, quot;UTF-8-MACquot;, quot;UCS-2BEquot;, quot;UCS-4BEquot;, quot;UCS-4LEquot;, quot;CP1251quot;, quot;localequot;, quot;externalquot;, quot;internalquot;]
  • 53. All String are Encoded • In Ruby 1.9 a String is a collection of encoded characters. raw bytes Encoding >> quot; quot;.encoding.name 1.9 => quot;UTF-8quot; Encoding object
  • 54. String works in characters 1.9 >> quot; quot;.reverse => quot; quot; >> quot; quot;.size => 2 >> quot; quot;.bytesize => 6
  • 55. String Indexing 1.9 1.8 >> quot;abcquot;[0] >> quot;abcquot;[0] => 97 => quot;aquot; >> quot; quot;[1] >> quot; quot;[1] => 184 => quot; quot; >> quot;abcquot;[0].ord => 97
  • 56. ! In Ruby 1.9, String has attached Encoding object, and works in characters.
  • 57. Transcoding utf8 = quot; quot; 1.9 utf8.bytesize # 6 utf8.bytes.to_a # [230, 184, 172, 232, 169, 166] big5 = utf8.encode(quot;big5quot;) big5.encoding.name # ”Big5” big5.bytesize # 4 big5.bytes.to_a # [180, 250, 184, 213]
  • 58. Transcoding fails str = quot;Résuméquot; 1.9 str.encode(quot;big5quot;) => Encoding::UndefinedConversionError: quot;xC3xA9quot; from UTF-8 to Big5 from (irb):2:in `encode' from (irb):2 from /usr/local/bin/irb19:12:in `<main>'
  • 59. Force Transcoding byte data utf8 = quot; quot; 1.9 big5 = utf8.encode(quot;big5quot;) big5.valid_encoding? => true big5.force_encoding(quot;utf-8quot;) big5.valid_encoding? => false
  • 60. Force Transcoding fails big5.valid_encoding? # false 1.9 big5 =~ /123456/ => ArgumentError: invalid byte sequence in UTF-8 from (irb):11 from /usr/local/bin/irb19:12:in `<main>'
  • 61. Encoding.compatible? : ASCII with a bigger Encoding ascii = quot;my quot;.force_encoding(quot;asciiquot;) 1.9 utf8 = quot;Résuméquot; # Encoding.compatible?(ascii, utf8) #<Encoding:UTF-8> # my_resume = ascii + utf8 puts my_resume # quot;My Résuméquot; puts my_resume.encoding.name # UTF-8
  • 62. Encoding.compatible? big5 = quot; quot;.encode(quot;big5quot;) 1.9 utf8 = quot;Résuméquot; # Encoding.compatible?(big5, utf8) # nil # big5 + utf8 => Encoding::CompatibilityError: incompatible character encodings: Big5 and UTF-8 from (irb):25 from /usr/local/bin/irb19:12:in `<main>'
  • 63. String Iteration each • Strings are no longer enumerable • Ruby 1.8 each() has been removed • 1.9 Ruby 1.9 use explicit iterator • each_line • each_byte • each_char • each_codepoint
  • 65. program source encoding magic comment # encoding: UTF-8 #!/usr/bin/env ruby -w # encoding: UTF-8 # coding: UTF-8 # -*- coding: UTF-8 -*-
  • 66. program without magic comment ruby foobar.rb # US-ASCII ruby -e foobar.rb irb # OS ($LC_CTYPE, $LANG) ruby -KU foobar.rb # UTF-8
  • 67. program source encoding error invalid multibyte char (US-ASCII)
  • 68. IO Object 1.9 # encoding: utf-8 f = File.open(quot;big5.txtquot;,quot;r:big5quot;) puts f.external_encoding # Big5 puts f.gets.encoding # Big5
  • 69. IO Object 1.9 # encoding: utf-8 f = File.open(quot;big5.txtquot;,quot;r:big5:utf-8quot;) puts f.external_encoding # Big5 puts f.internal_encoding # UTF-8 puts f.gets.encoding # UTF-8
  • 70. IO Object 1.9 # encoding: utf-8 f = File.open(quot;another_big5.txtquot;, quot;w:big5quot;) puts f.external_encoding # Big5 data = quot; quot; puts data.encoding.name # UTF-8 f << data
  • 71. IO Object 1.9 # encoding: utf-8 f = File.open(quot;another_big5.txtquot;, quot;w:big5quot;) puts f.external_encoding # Big5 data = quot; quot; puts data.encoding.name # UTF-8 f << data
  • 72. Regexp has encoding too • Oniguruma engine 1.9 http://www.geocities.jp/kosako3/oniguruma/ /w/.encoding • Same basic API => #<Encoding:US-ASCII> • better performance / /.encoding => #<Encoding:UTF-8> • support for a lot of encoding • extended syntax
  • 73. Default Encoding Overview • String literal program source • Symbols Regexp 7-bit US-ASCII program source • IO external_encoding OS • ruby -E • Encoding.external_encoding
  • 75. Fibers (semi-coroutine) code block
  • 76. f = Fiber.new { 1.9 2.times do puts quot;Fiber say hiquot; Fiber.yield # puts quot;Fiber say byequot; end }# >> f.resume # Fiber say hi >> f.resume # Fiber say bye # Fiber say hi >> f.resume # Fiber say bye >> f.resume FiberError: dead fiber called from (irb):78:in `resume' from (irb):78 from /usr/local/bin/irb19:12:in `<main>'
  • 77. Fibers • Enumerator • fiber library fiber object • (Ruby 1.8 continuation continuation kernel library) • ... zzz
  • 78. Native Threads • Green threads 1.8 Ruby thread native thread • Native (operation system) thread 1.9 Ruby thread native thread
  • 79. GIL Giant Interpreter Lock • 1.9 C extension libraries thread safe Thread ( Ruby Threads JRuby)
  • 80. 4. Ruby on Rails
  • 81. Ruby 1.9 on Rails • Rails 2.3.2 or edge • mysql-ruby driver for Ruby 1.9 • Passenger(mod_rails) or Thin
  • 82. Upgrade issue • program source encoding problem • invalid multibyte char # encoding: UTF-8 • encoding compatibility problem • ACSII-8BIT (binary) UTF-8 String • http://github.com/hectoregm/mysql-ruby (UTF-8 friendly) • some gem, plugins are not Ruby 1.9 compatible • http://isitruby19.com/
  • 83. Benchmark • Rails 2.3.2 production mode • No DB, just render :text => 'hello' • My MacBook Pro 2.2G • httperf
  • 84. Performance Reply rate [replies/s] min avg max stddev Ruby 1.8.6 241.8 258.3 267.4 14.4 Mongrel 1.1.5 Ruby 1.8.6 244.6 260.9 271.2 11.4 mod_rails Ruby 1.9.1 264.0 269.5 273.4 4.9 mod_rails Ruby 1.8.6 244.5 273.2 299.6 22.7 Thin 1.0.0 Ruby 1.9.1 348.4 363.2 371.2 12.8 Thin 1.0.0
  • 85. Performance Ruby 1.9 Rails Stack !! 400 300 Ruby 1.8.6/Mongrel 1.1.5 Ruby 1.8.6/mod_rails edge 200 Ruby 1.9.1/mod_rails edge Ruby 1.8.6/Thin 1.0.0 Ruby 1.9.1/Thin 1.0.0 100 0 Reply rate [replies/s]
  • 86. Performance Ruby 1.9 Rails Stack !! 400 300 Ruby 1.8.6/Mongrel 1.1.5 Ruby 1.8.6/mod_rails edge 200 Ruby 1.9.1/mod_rails edge Ruby 1.8.6/Thin 1.0.0 Ruby 1.9.1/Thin 1.0.0 100 0 Reply rate [replies/s]
  • 88. TIOBE Programming Community Index for April 2009
  • 89. Ruby challenge • Ruby 1.9 change a lot and 1.8 is slow and should be deprecated. • Migrate to Ruby 1.9 is the big challenge in 2009.
  • 90. Reference • Understanding M17n http://blog.grayproductions.net/articles/understanding_m17n • Books • Programming Ruby 1.9 (Pragmatic) • The Ruby Programming Language (O’Reilly) • Ruby Best Practices (O’Reilly) • The Well-Grounded Rubyist (Manning) • Slide • MigrationToRuby 1.9 • Ruby 1.9: What to Expect http://slideshow.rubyforge.org/ruby19.html • Matz on Ruby 1.9
  • 91. Other reference links • http://svn.ruby-lang.org/repos/ruby/tags/v1_9_1_0/NEWS • http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed • http://blog.grayproductions.net/articles/getting_code_ready_for_ruby_19 • http://dablog.rubypal.com/2009/1/14/10-things-to-be-aware-of-in-moving-to- ruby-1-9 • http://dablog.rubypal.com/2009/1/16/son-of-10-things-to-be-aware-of-in- ruby-1-9 • http://blog.kineticweb.com/articles/2009/01/30/ruby-1-9-1-the-other-features
  • 93. Bonus
  • 94. Object#tap puts quot;dogquot;.reverse .tap{ |o| puts quot;reversed: #{o}quot; } .upcase # reversed: god GOD