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

Random Ruby (and Rails) Tips

Random Ruby (and Rails) Tips

Slides for Oedo Ruby Kaigi 04, presented on 19 April 2014.

http://regional.rubykaigi.org/oedo04/

Winston

April 19, 2014
Tweet

More Decks by Winston

Other Decks in Programming

Transcript

  1. Random
    Ruby Tips
    and
    Rails
    30

    View full-size slide

  2. Winston
    @winstonyw

    View full-size slide

  3. ͔͜͜ΒӳޠΛ࢖͍·͢ɻ
    ͝ΊΜͳ͍͞ʂ

    View full-size slide

  4. RubyAsia.com
    A fortnightly newsletter for Ruby news and articles from Asia

    View full-size slide

  5. June 26 - 27, 2014
    Singapore
    http://www.reddotrubyconf.com

    View full-size slide

  6. SG Ruby Group
    http://www.meetup.com/Singapore-Ruby-Group/

    View full-size slide

  7. Random
    Ruby Tips
    and
    Rails
    30

    View full-size slide

  8. >> "Hello World"
    => "Hello World”
    !
    >> string = _
    => "Hello World”
    !
    >> string
    => "Hello World"
    #1
    Underscore as Last Returned Value
    irb

    View full-size slide

  9. >> n = 5000000
    => 5000000
    !
    >> m = 5_000_000
    => 5000000
    !
    >> n == m
    => true
    #2
    Underscore as Separator
    irb

    View full-size slide

  10. #3
    Array Initialization
    Array(x).each do |x|
    puts x
    end
    if x.is_a? Array
    x.each { |x| puts x }
    else
    puts x
    end

    View full-size slide

  11. #4
    Hash Default
    >> hash = Hash.new(:default)
    !
    >> hash[:not_found]
    => :default
    !
    >> hash.fetch(:not_found)
    KeyError: key not found: :not_found
    irb

    View full-size slide

  12. #5
    Hash Fetch and Default
    >> hash = Hash.new
    !
    >> hash.fetch(:not_found, :default)
    => :default
    !
    >> hash.fetch(:not_found) {|e| "#{e} default"}
    => "not_found default"
    irb

    View full-size slide

  13. Hash Map (1)
    >> hash.inject({}) do |new_hash, (k,v)|
    >> new_hash[k] = v*2
    >> new_hash
    >> end
    => {:a => 2, :b => 4}
    irb
    Convert {a: 1, b: 2} To {a: 2, b: 4}
    #6

    View full-size slide

  14. #7
    Hash Map (2)
    >> Hash[hash.map{ |k,v| [k, v*2] }]
    => {:a => 2, :b => 4}
    !
    >> hash.map{ |k,v| [k, v*2] }
    => [[:a, 2], [:b, 4]]
    !
    >> Hash[[[:a, 2], [:b, 4]]]
    => {:a => 2, :b => 4}
    irb
    Convert {a: 1, b: 2} To {a: 2, b: 4}

    View full-size slide

  15. #8
    Hash Map (3)
    >> hash.merge(hash) { |key, oldval, newval| newval*2 }
    => {:a => 2, :b => 4}
    !
    >> hash.merge(hash) { |_, _, newval| newval*2 }
    => {:a => 2, :b => 4}
    irb
    Convert {a: 1, b: 2} To {a: 2, b: 4}

    View full-size slide

  16. #9
    Case Conditions
    >> whichcase(1)
    => "I am an integer."
    >> whichcase("1")
    => "I am a string."
    >> whichcase(3)
    => "I am either 2 or 3."
    >> whichcase(4)
    => "I belong to a range."
    >> whichcase(8)
    => "I belong to a range."
    >> whichcase(20)
    => "I am 20!"
    >> whichcase(:nobody)
    => "I am nobody."
    irb
    def whichcase(num)
    case num
    when 1
    "I am an integer."
    when "1"
    "I am a string."
    when 2, 3
    "I am either 2 or 3."
    when 4..10
    "I belong to a range."
    when ->(x) { x == 20 }
    "I am 20!"
    else
    "I am nobody."
    end
    end

    View full-size slide

  17. >> %w(hello world).map { |s| s.upcase }
    => ["HELLO", “WORLD"]
    !
    >> %w(hello world).map(&:upcase)
    => ["HELLO", "WORLD"]
    #10
    Symbol to Proc to Block
    irb
    http://stackoverflow.com/questions/14881125/what-does-to-proc-method-mean

    View full-size slide

  18. >> numbers = [1, 2, 3, 4]
    => [1, 2, 3, 4]
    !
    >> numbers.inject(&:+)
    => 10
    #11
    Symbol to Proc to Block
    irb

    View full-size slide

  19. >> %(hello world).map(&Star)
    >> ["** hello **", "** world **"]
    #12
    Symbol to Proc to Block
    irb
    class Star
    def self.to_proc
    lambda { |x| "** #{x} **" }
    end
    end

    View full-size slide

  20. #13
    Exceptions Hierarchy
    def rescue_exception
    begin
    boom
    rescue Exception => e
    puts "Rescued: #{e}"
    end
    end
    Bad!!!
    Exception
    NoMemoryError
    ScriptError
    LoadError
    NotImplementedError
    SyntaxError
    SecurityError
    SignalException
    Interrupt
    StandardError
    ArgumentError
    EncodingError
    FiberError
    IOError
    IndexError
    KeyError
    StopIteration
    LocalJumpError
    NameError
    NoMethodError
    RangeError
    FloatDomainError
    RegexpError
    RuntimeError
    SystemCallError
    ThreadError
    TypeError
    ZeroDivisionError
    SystemExit
    SystemStackError
    fatal

    View full-size slide

  21. #14
    Rescue Refactoring
    def rescue_exception
    boom
    rescue NameError => e
    puts "Rescued: #{e}"
    end
    def rescue_exception
    begin
    boom
    rescue Exception => e
    puts "Rescued: #{e}"
    end
    end

    View full-size slide

  22. Source Location
    #15
    >> src = " ".method(:blank?).source_location
    => ["/vagrant/rails/activesupport/lib/active_support/
    core_ext/object/blank.rb", 116]
    !
    >> `subl #{src[0]}:#{src[1]}`
    !
    >> " ".method(:slice).source_location
    => nil
    irb

    View full-size slide

  23. $> ruby data.rb
    !
    --> Read Data
    Position: 192
    Hello World!
    --> Read Data Again
    Position: 192
    Hello World!
    #16
    Reading DATA in a Ruby File
    shell
    position = DATA.pos
    !
    puts "--> Read Data"
    puts "Position: #{position}"
    puts DATA.read
    !
    puts "--> Read Data Again"
    DATA.seek position
    puts "Position: #{position}"
    puts DATA.read
    !
    __END__
    Hello World!

    View full-size slide

  24. $> echo "super\nsize\nme" | ruby -ne 'puts $_.upcase'
    SUPER
    SIZE
    ME
    #17
    Command-line Ruby
    shell

    View full-size slide

  25. $> ruby -run -e httpd . -p 8080
    #18
    Simple Ruby Server
    shell
    https://github.com/ruby/ruby/blob/trunk/lib/un.rb

    View full-size slide

  26. >> require 'open-uri'
    !
    >> big = open("http://localhost:8080/big.txt")
    => #
    !
    >> small = open("http://localhost:8080/small.txt")
    => #
    #19
    OpenURI, Tempfile and StringIO
    irb
    15KB
    12Kb

    View full-size slide

  27. >> OpenURI::Buffer::StringMax
    => 10240
    !
    >> OpenURI::Buffer.send :remove_const, 'StringMax'
    => 10240
    !
    >> OpenURI::Buffer.const_set 'StringMax', 0
    => 0
    #19
    OpenURI, Tempfile and StringIO
    irb

    View full-size slide

  28. >> require 'open-uri'
    !
    >> big = open("http://localhost:8080/big.txt")
    => #
    !
    >> small = open("http://localhost:8080/small.txt")
    => #
    #19
    OpenURI, Tempfile and StringIO
    irb

    View full-size slide

  29. #20
    Singleton Module
    >> OneAndOnly.instance === OneAndOnly.instance
    => true
    !
    >> OneAndOnly.new
    NoMethodError: private method `new' called for
    OneAndOnly:Class
    irb
    require 'singleton'
    class OneAndOnly
    include Singleton
    end
    http://www.ruby-doc.org/stdlib-2.1.1/libdoc/singleton/rdoc/Singleton.html

    View full-size slide

  30. >> mq = MyQueue.new
    => #
    !
    >> mq.enq(1)
    => [1]
    !
    >> mq.enq(2)
    => [1, 2]
    !
    >> mq.size
    => 2
    !
    >> mq.deq
    => 1
    #21
    Forwardable Module
    irb
    class MyQueue
    extend Forwardable
    !
    def_delegator :@q, :push , :enq
    def_delegator :@q, :shift, :deq
    !
    def_delegators :@q, :[], :size
    !
    def initialize
    @q = []
    end
    end
    http://www.ruby-doc.org/stdlib-2.1.1/libdoc/forwardable/rdoc/Forwardable.html

    View full-size slide

  31. #22
    Bundler Jobs
    $> time bundle install
    78.55s user 21.97s system 17% cpu 9:20.32 total
    !
    $> time bundle install -j4
    83.05s user 23.84s system 54% cpu 3:16.18 total
    shell
    http://bundler.io/v1.5/whats_new.html

    View full-size slide

  32. #23
    Bundler Jobs Config
    $> cores=`sysctl -n hw.ncpu`
    $> bundle config --global jobs $((cores))
    !
    $> cat ~/.bundle/config
    —-
    BUNDLE_JOBS: ‘4’
    shell
    http://bundler.io/v1.5/whats_new.html

    View full-size slide

  33. #24
    Bundler Commands
    $> bundle outdated
    # List installed gems with newer versions available
    !
    $> bundle console
    # Opens an IRB session with the Gemfile pre-loaded
    shell
    http://bundler.io/v1.6/commands.html

    View full-size slide

  34. class AddNameToProducts < ActiveRecord::Migration
    def change
    add_column :products, :name, :string
    add_index :products, :name
    end
    end
    Migration Syntax
    #25
    https://github.com/rails/rails/blob/master/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
    $> rails generate migration create_product
    AddNameToProducts name:string:index
    shell

    View full-size slide

  35. class AddCategoryIdToProducts < ActiveRecord::Migration
    def change
    add_reference :products, :category_id, index: true
    end
    end
    Migration Syntax
    #26
    https://github.com/rails/rails/blob/master/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
    $> rails generate migration create_product
    AddCategoryIdToProducts category_id:references
    shell

    View full-size slide

  36. Sandboxed Console
    #27
    $> rails console —-sandbox
    Any modifications you make will be rolled back on exit
    !
    >> Product.all
    => #
    !
    >> Product.create(name: “walkman")
    (0.0ms) SAVEPOINT active_record_1
    SQL (1.7ms) INSERT INTO “products” ...
    (0.0ms) RELEASE SAVEPOINT active_record_1
    => #
    !
    >> exit
    (2.1ms) rollback transaction
    irb

    View full-size slide

  37. Rake Notes
    #28
    $> rake notes
    app/controllers/application_controller.rb:
    * [2] [TODO] remember to do this
    * [3] [FIXME] remember to fix this
    * [4] [OPTIMIZE] remember to optimize this
    irb
    class ApplicationController < ActionController::Base
    # TODO: remember to do this
    # FIXME: remember to fix this
    # OPTIMIZE: remember to optimize this
    end
    Uppercase Only!
    cd railsapp; rake -T

    View full-size slide

  38. class UglyText
    def self.print
    puts <<-HERE
    I am not indented.
    But I am ugly on the inside.
    HERE
    end
    end
    Pretty Heredoc
    #29
    >> UglyTest.print
    I am not indented.
    But I am ugly on the inside.
    irb

    View full-size slide

  39. class NiceText
    def self.print
    puts <<-HERE.strip_heredoc
    I am not indented.
    And I look good on the inside.
    HERE
    end
    end
    Pretty Heredoc
    #29
    >> NiceTest.print
    I am not indented.
    And I look good on the inside.
    irb

    View full-size slide

  40. Question?
    #30
    require 'active_support'
    !
    class Winston
    cattr_writer :emotion
    def self.is
    ActiveSupport::StringInquirer.new(@@emotion)
    end
    end
    >> Winston.emotion = "happy"
    >> Winston.is.happy?
    => true
    irb

    View full-size slide

  41. Sean Xie
    Dr. Khoo Chong Yee
    Teo Yinquan
    Teo Hui Ming
    Karthik T
    Credits

    View full-size slide

  42. Thank You
    @winstonyw

    View full-size slide