Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby 2.0 on Rails in Production

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Ruby 2.0 on Rails in Production

Slides for RedDotRubyConf talk "Ruby 2.0 on Rails in Production" http://www.reddotrubyconf.com/schedule#amatsuda

Avatar for Akira Matsuda

Akira Matsuda

June 08, 2013
Tweet

More Decks by Akira Matsuda

Other Decks in Programming

Transcript

  1. rails command boot time # ruby 1.9.3p429 % time rails

    r '1' rails r '1' 7.00s user 1.67s system 99% cpu 8.701 total % time rails r '1' rails r '1' 7.03s user 1.64s system 99% cpu 8.698 total % time rails r '1' rails r '1' 7.01s user 1.66s system 99% cpu 8.710 total # ruby 2.0.0p195 % time rails r '1' rails r '1' 4.80s user 1.29s system 99% cpu 6.124 total % time rails r '1' rails r '1' 4.77s user 1.28s system 99% cpu 6.073 total % time rails r '1' rails r '1' 4.78s user 1.29s system 99% cpu 6.099 total
  2. Branch Maintenance Policies 1.8.7: maintained by @shyouhei, will be dead

    soon 1.8.8: no plan 1.9.0: dead 1.9.1: dead 1.9.2: maintained by @yugui, dead (?) 1.9.3: maintained by @unak 1.9.4: no plan 2.0.0: maintained by @nagachika 2.0.1: no plan 2.1.0: managed by @naruse
  3. @mametter (mame) eval$C=%q(at_exit{ open("/dev/dsp","wb"){|g|h=[0]*80 $><<"\s"*18+"eval$C=%q(#$C);S=%:" (S<<m=58).lines{|l|s=[128]*n=20E2 t=0; h.map!{|v|d=?!==l[ t]?1 :(l[

    t]== ?#)? 0*v= 6:03 (v<1 ?[]: 0..n -1). each {|z| s[z] +=2* M.sin(($*[0] ||1) .to_f*M.sin(y= 40*(z+m)*2** (t/12E0)/463)+ y)*(v-z*d/n)}; t+=1;v-d};m+= n;g.flush<<(s. pack"C*"); puts(l)}}};M= Math);S=%: Jesu, Joy of Man's Desiring Johann Sebastian Bach # | # | # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # | | | # | #| # # # | # | | | # | | # # # # # # | | # | | | # # # # # # | | | # | | # # # # # | | # | | # # | # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | | # # # # # # | | | # | # # # # # | | | # | # | # # # # # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
  4. Hello...? % ruby -v hello_utf8.rb ruby 1.8.7 (2012-06-29 patchlevel 370)

    [i686-darwin12.2.1] ͜Μʹͪ͸ʂ % ruby -v hello_utf8.rb ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.3.0] encoding_utf8.rb:1: invalid multibyte char (US-ASCII)
  5. Hello...? % ruby -v hello_utf8.rb ruby 1.8.7 (2012-06-29 patchlevel 370)

    [i686-darwin12.2.1] ͜Μʹͪ͸ʂ % ruby -v hello_utf8.rb ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.3.0] encoding_utf8.rb:1: invalid multibyte char (US-ASCII) % ruby -v hello_utf8.rb ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.3.0] ͜Μʹͪ͸ʂ
  6. Incompatibility % ruby -v encoding_binary.rb ruby 1.9.3p429 (2013-05-15 revision 40747)

    [x86_64-darwin12.3.0] "\xE3\x81\x82" 3 % ruby -v encoding_binary.rb ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.3.0] "͋" 1
  7. Tiny Print Debugging Tip % ruby encoding_binary.rb {:str=>"͋", :size=>1} (by

    @yhara: http://route477.net/d/?date=20130206#p01)
  8. AMC class A def foo puts 'foo' end end class

    A def foo_with_bar foo_without_bar puts ‘bar’ end alias_method_chain :foo, :bar end A.new.foo #=> foo bar
  9. Module#prepend class A def foo; puts 'foo'; end end module

    Bar def foo super puts 'bar' end end class A prepend Bar end A.new.foo #=> foo bar
  10. Method#parameters class C def m(a, b = 1, c =

    nil) end end C.new.method(:m).parameters #=> [[:req, :a], [:opt, :b], [:opt, :c]]
  11. Initial implementation module AbstractController class Base def send_action(method_name, *args) return

    send method_name, *args unless args.blank? values = method(method_name).parameters.map(&:last).map {|k| params[k]} send method_name, *values end end end
  12. Test Patterns params = {a: '1', b: '2'} def m

    end #=> [] def m(a) end #=> ['1'] def m(a = 'a') end #=> ['1'] def m(c = 'c') end #=> expected: ['c'], actual: [nil]
  13. Don't add to the arguments if (type == :opt) &&

    !params.has_key? params = {a: '1', b: '2'} def m(c = 'c') end #=> ['c'] def m(a, b) end #=> ['1', '2'] def m(a, b = 'b') end #=> ['1', '2'] def m(a, c = 'c') end #=> ['1', 'c'] def m(a = 'a', b = 'b') end #=> ['1', '2'] def m(c = 'c', d = 'd') end #=> ['c', 'd'] def m(c = 'c', a) end #=> expected: ['c', '1'], actual: ['1']
  14. RubyVM::InstructionSequence # warning: Do never use this black magic!! def

    foo(x = 'xx', y = :yy, z = 1); end ary = RubyVM::InstructionSequence.of(method(:foo)).to_a default_args = ary[11][1] bytecode = ary[13] p default_args #=> [:label_0, :label_4, :label_8, :label_11] p bytecode #=> [:label_0, 2, [:putstring, "xx"], [:setlocal_OP__WC__0, 4], :label_4, [:putobject, :yy], [:setlocal_OP__WC__0, 3], :label_8, [:putobject_OP_INT2FIX_O_1_C_], [:setlocal_OP__WC__0, 2], :label_11, [:trace, 8], [:putnil], [:trace, 16], [:leave]]
  15. method.parameters.reverse_each do |type, key| do the same thing params =

    {a: '1', b: '2'} def m(c = 'c', a) end => ['c', '1']
  16. We needed to do this because, Method parameters are just

    an Array So the order matters It's a pain I wish if the method parameter is more like a Hash, labeled by the de ned method argument names
  17. Keyword arguments # traditional method def m(a, b = 'b',

    c = 'c') end m('1', '2', '3') # kwargs def m(a, b: 'b', c: 'c') end m('1', b: '2', c: '3')
  18. Keyword arguments Optional parameters can be written as a Hash.

    Order doesn't matter action_args now supports kwargs, so you can use it in your controller code
  19. kwargs and Rails Rewriting Rails code using kwargs More comprehensible

    API def foo(options_with_some_unknown_keys_and_defaults = {}) def bar(*values_maybe_or_maybe_not_with_options) ⊗ def foo(x: 1, y: 2, z: 2) def bar(*values, **options)
  20. kwargs and Rails (AS) # AS/lib/active_support/core_ext/class/attribute_accessors.rb - def cattr_reader(*syms) -

    options = syms.extract_options! + def cattr_reader(*syms, instance_reader: true, instance_accessor: true) ... - unless options[:instance_reader] == false || options[:instance_accessor] == false + unless (instance_reader == false) || (instance_accessor == false)
  21. kwargs and Rails (AMo) # AMo/lib/active_model/validations/validates.rb - def validates(*attributes) -

    defaults = attributes.extract_options!.dup + def validates(*attributes, **defaults)
  22. kwargs and Rails (AP) # AP/lib/action_view/helpers/text_helper.rb - def cycle(first_value, *values)

    - options = values.extract_options! - name = options.fetch(:name, 'default') - + def cycle(first_value, *values, name: 'default')
  23. kwargs and Rails (:if, :unless) User.validates_presence_of :name, :if => ->

    { true } # AMo/lib/active_model/validations/presence.rb - def validates_presence_of(*attr_names) + def validates_presence_of(*attr_names, if: true, unless: false, on: nil, strict: nil)
  24. :if!? def m(if: true) if if ... end end #=>

    "syntax error, unexpected keyword_end"
  25. kwargs and Rails (:end) # actionpack/lib/action_view/helpers/date_helper.rb - def build_options(selected, options

    = {}) - options = { - leading_zeros: true, ampm: false, use_two_digit_numbers: false - }.merge!(options) - - start = options.delete(:start) || 0 - stop = options.delete(:end) || 59 - step = options.delete(:step) || 1 - leading_zeros = options.delete(:leading_zeros) + def build_options(selected, start: 0, end: 59, step: 1, leading_zeros: true, ampm: false, use_two_digit_numbers: false)
  26. :end!? def m(end: 'omg') p end end #=> "syntax error,

    unexpected keyword_end, expecting end-of-input"
  27. We created a new gem Named it "debugger2" (ko1 named

    it. Not me!) Based on new debugger API
  28. end