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

Ruby 2.0 on Rails in Production

Ruby 2.0 on Rails in Production

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

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