Common Ruby Idioms

前端 未结 15 1897
星月不相逢
星月不相逢 2020-12-07 07:13

One thing I love about ruby is that mostly it is a very readable language (which is great for self-documenting code)

However, inspired by this question: Ruby Code ex

相关标签:
15条回答
  • 2020-12-07 07:38

    I would suggest reading through the code of popular and well designed plugins or gems from people you admire and respect.

    Some examples I've run into:

    if params[:controller] == 'discussions' or params[:controller] == 'account'
      # do something here
    end
    

    corresponding to

    if ['account', 'discussions'].include? params[:controller]
      # do something here
    end
    

    which later would be refactored to

    if ALLOWED_CONTROLLERS.include? params[:controller]
      # do something here
    end
    
    0 讨论(0)
  • 2020-12-07 07:42

    I maintain a wiki page that covers some Ruby idioms and formatting:

    https://github.com/tokland/tokland/wiki/RubyIdioms

    0 讨论(0)
  • 2020-12-07 07:43

    The magic if clause that lets the same file serve as a library or a script:

    if __FILE__ == $0
      # this library may be run as a standalone script
    end
    

    Packing and unpacking arrays:

    # put the first two words in a and b and the rest in arr
    a,b,*arr = *%w{a dog was following me, but then he decided to chase bob}
    # this holds for method definitions to
    def catall(first, *rest)
      rest.map { |word| first + word }
    end
    catall( 'franken', 'stein', 'berry', 'sense' ) #=> [ 'frankenstein', 'frankenberry', 'frankensense' ]
    

    The syntatical sugar for hashes as method arguments

    this(:is => :the, :same => :as)
    this({:is => :the, :same => :as})
    

    Hash initializers:

    # this
    animals = Hash.new { [] }
    animals[:dogs] << :Scooby
    animals[:dogs] << :Scrappy
    animals[:dogs] << :DynoMutt
    animals[:squirrels] << :Rocket
    animals[:squirrels] << :Secret
    animals #=> {}
    # is not the same as this
    animals = Hash.new { |_animals, type| _animals[type] = [] }
    animals[:dogs] << :Scooby
    animals[:dogs] << :Scrappy
    animals[:dogs] << :DynoMutt
    animals[:squirrels] << :Rocket
    animals[:squirrels] << :Secret
    animals #=> {:squirrels=>[:Rocket, :Secret], :dogs=>[:Scooby, :Scrappy, :DynoMutt]}
    

    metaclass syntax

    x = Array.new
    y = Array.new
    class << x
      # this acts like a class definition, but only applies to x
      def custom_method
         :pow
      end
    end
    x.custom_method #=> :pow
    y.custom_method # raises NoMethodError
    

    class instance variables

    class Ticket
      @remaining = 3
      def self.new
        if @remaining > 0
          @remaining -= 1
          super
        else
          "IOU"
        end
      end
    end
    Ticket.new #=> Ticket
    Ticket.new #=> Ticket
    Ticket.new #=> Ticket
    Ticket.new #=> "IOU"
    

    Blocks, procs, and lambdas. Live and breathe them.

     # know how to pack them into an object
     block = lambda { |e| puts e }
     # unpack them for a method
     %w{ and then what? }.each(&block)
     # create them as needed
     %w{ I saw a ghost! }.each { |w| puts w.upcase }
     # and from the method side, how to call them
     def ok
       yield :ok
     end
     # or pack them into a block to give to someone else
     def ok_dokey_ok(&block)
        ok(&block)
        block[:dokey] # same as block.call(:dokey)
        ok(&block)
     end
     # know where the parentheses go when a method takes arguments and a block.
     %w{ a bunch of words }.inject(0) { |size,w| size + 1 } #=> 4
     pusher = lambda { |array, word| array.unshift(word) }
     %w{ eat more fish }.inject([], &pusher) #=> ['fish', 'more', 'eat' ]
    
    0 讨论(0)
提交回复
热议问题