Because I need to use Ruby and Rails for my work, I spent some time to learn it quickly during the Dragon Boat Festival holiday. Here’s a quick note.

Underlying data types

In Ruby, everything is an object. Each object has a unique object identifier (abbreviated object ID)

  • Integer type (numbers)

    Integers are objects of the Fixnum and Bignum classes. Fixnum objects can hold integers one bit less than the native byte length. When a Fixnum exceeds this range, it is automatically converted to a Bignum object, whose range of representations is limited only by the size of available memory. If the result of an operation on a Bignum object can be represented as Fixnum, the result will be returned as Fixnum

    An integer consists of an optional symbolic mark, an optional base indicator (0 for octal, 0d for decimal, 0x for hexadecimal, and 0b for binary), and a string of corresponding bases. Underscores in numeric strings are ignored

    123456 = > 123456# Fixnum
    0d123456                => 123456               # Fixnum123 _456 = > 123456# Fixnum - Ignore underscores- = > 543-543# Fixnum - negative number
    0xaabb                  => 43707                # Fixnum - hexadecimal0377 = > 255# Fixnum - octal
    -0b10_1010              => -42                  # Fixnum - binary (negative)123 _456_789_123_456_789 = > 123456789123456789# Bignum
    Copy the code
  • Floats (floats)

    A numeric literal with a decimal point or exponent is considered a Float object, which is the same size as the double data type on the local machine. There must be at least one digit before and after the decimal point. A string like 1.e3 will attempt to call the e3 method of the Fixnum class

    12.34 => 12.34-0.1234e2 => -12.34 1234E-2 => 12.34Copy the code
  • String (strings)

    Ruby provides a variety of mechanisms for generating literal strings. Each mechanism produces objects of type String. The difference between the different mechanisms is how do you separate strings and what substitutions do you make in literal content

    String literals with single quotes perform the fewest substitutions. Examples include ‘stuff’ and %q/stuff/, both of which convert \\ to a single backslash and \’ to single quotes. All other backslashes are not converted

    'hello'                     => hello
    'a backslash \'\ \ \' '        => a backslash '\'
    %q/simple string/           => simple string
    %q(nesting (really) works)  => nesting (really) works
    %q no_blanks_here ;         => no_blanks_here
    Copy the code

    Double quoted strings such as “stuff”, %Q/stuff/ and %/stuff/ also perform additional substitutions

    a = 123
    "\123mile"                  => Smile
    "Say \"Hello\""             => Say "Hello"
    %Q!"I said 'nuts',"I said! = >"I said 'nuts'," I said
    %Q{Try #{a+1}, not #{a-1}} => Try 124, not 122
    %<Try #{a+1}, not #{a-1}> => Try 124, not 122
    "Try #{a+1}, not #{a-1}"    => Try 124, not 122
    %{#{ a=1; b=2; a+b }} => 3
    Copy the code
  • Interval (ranges)

    The interval uses the expression expr.. Expr and expr… Expr to build Range objects. The form of two points is the closed interval (including the value on the right), while the form of three points is half open and half closed (excluding the value on the right).

    > (1.. 5).each {|n| puts n} 1 2 3 4 5 > (1... 5).each {|n| puts n} 1 2 3 4Copy the code
  • Array (arrays)

    Array class literals are a comma-separated series of object references between square brackets. Trailing commas are ignored. Arrays can also be formed with the abbreviations %w and %w

    Arr = [: Fred, 10, 3.14,"this is a string"."pebbles", ]
            => [:fred, 10, 3.14, "this is a string"."pebbles"]
    
    arr = %w( fred wilma barney betty great\ gazoo )
            => ["fred"."wilma"."barney"."betty"."great gazoo"] arr = %w( Hey! \tIt is now -#{Time.now}-)= > ["Hey! \\tIt"."is"."now"."-\#{Time.now}-"] arr = %W( Hey! \tIt is now -#{Time.now}-)= > ["Hey! \tIt"."is"."now"."- the 2019-06-09 11:35:50 + 0800 -"]
    Copy the code

    Array objects can access individual elements by providing an index between square brackets. Ruby’s array index starts from zero

    a = [1, 'cat', 3.14] = > a three element array [0] = > 1 a [2] = nil = > set a third element = > [1,"cat", nil]
    Copy the code
  • Hash table (hashes)

    Ruby Hash literals consist of a list of key/value pairs in curly braces, separated by commas, and separated by => sequences. Trailing commas are ignored. All keys and values in a specific hash table are not required to be of the same type. The key in the hash table must be able to respond to the hash message and return a hash code, and the hash code corresponding to the key cannot be changed. The keys in the hash table must also be eQL. To compare

    colors = {
      "red"   => 0xf00,
      "green" => 0x0f0,
      "blue"  => 0x00f,
    }
    Copy the code

    Hash tables are also indexed using the same square bracket notation as arrays

    colors["red"]           => 3840
    colors["white"] = 0xfff => 4095
    colors                  => {"red"= > 3840,"green"= > 240,"blue"= > 15,"white"= > 4095}Copy the code
  • Symbol (symbols)

    Ruby’s symbol is an identifier that corresponds to a string (usually a name). You can construct the symbol for a name by prefixing it with a colon, or you can create the symbol for any string literal by prefixing it with a colon. Substitution occurs in double-quoted strings. No matter how the program uses names, a specific name or string always produces the same symbol, right

    :Object
    :my_variable
    :"Ruby rules"
    a = 'cat'
    :'catsup'       => :catsup
    :"#{a}sup"      => :catsup
    :'#{a}sup'= > :"\#{a}sup"
    Copy the code

    Other languages call this process interning and the symbols atoms

  • Regular expressions

    Regular expression literals are objects of type Regexp. Regular expressions can be created either explicitly by calling the regexp. new constructor, or implicitly using the literal form /pattern/ and %r{pattern}

    /pattern/
    /pattern/options
    %r{pattern}
    %r{pattern}options
    Regexp.new('pattern' [, options])
    Copy the code

    Once you have a regular expression object, you can use Regexp#match(string) or the match operators =~(must match) and! ~(negative match) matches a string

    name = "Fats Waller"
    name =~ /a/             => 1
    name =~ /z/             => nil
    /a/ =~ name             => 1
    Copy the code

    The match operators have the side effect of setting some Ruby variables. $& gets the part of the string that matches the pattern, $’ gets the part of the string that matches before, and $’ ‘gets the part of the string that matches after

    $& => A pattern matches the string $' => F pattern matches the previous string $'=> ts Waller pattern matches after the stringCopy the code

Variables and Constants

Ruby names are used to refer to common, variable, method, class, and module names. The first character must be an uppercase letter, lowercase letter, or underscore, followed by any combination of uppercase letter, lowercase letter, underscore, or digit

  • Local variable name

    A character combination consisting of lowercase letters followed by names. In general, use underscores instead of camelCase for multi-word names

    three_two_one = 321
    Copy the code
  • Instance variable name

    It starts with an @ followed by a name. It’s a good idea to use lowercase after the @

    @name   @_    @size
    Copy the code
  • Class variable name

    It starts at @@, followed by a name

    @@name  @@_   @@size
    Copy the code
  • Name of a const variable

    Start with a capital letter followed by multiple nomenclature characters. Class names and module names are constants, so follow the naming tradition of constants. Traditionally, constant object references are made up of uppercase letters and underscores, while class and module names are mixedcases

    Module Math ALMOST_PI = 22.0/7.0 end Class BigBlob endCopy the code
  • Global variable names

    Consists of the dollar character $followed by the naming character. Global variables can be modified anywhere in the program and are generally not recommended

    $temp = "this is a global variable"
    Copy the code
  • Multiple assignments

    Ruby can assign values to a group of variables simultaneously. If the variable is preceded by *, Ruby will wrap the unallocated value as an array and assign it to the variable

    A, b, c = 1, 2, 3 a, b, c = 1, 2, 3, 4, 5 = > a = 1, b = 2, c = (three, four, five), a * b, c = 1, 2, 3, 4, 5 = > a = 1, b = [4] 2, c = 5Copy the code

conditional

  • Conditional and true and false

    In Ruby, only false and nil are false, and all other values represent true. In addition, there is a general rule in Ruby that, in order to make programs easy to understand, all methods that return true and false should be called? At the end

  • Logical operator

    In Ruby logical operators &&, | | and! , as well as the same but slightly lower priority logical operators and, or, not. Usually the former is used for logical judgment and the latter for process control

    Condition 1 and condition 2 must both be true, and the expression returns true

    Condition 1 &condition 2 condition 1 and condition 2Copy the code

    If either condition 1 or condition 2 is true, the expression returns true

    Condition 1 | | conditions condition 1 or 2Copy the code

    Takes the opposite condition and returns the opposite logic of the conditional expression

    ! Condition not conditionCopy the code
  • Comparison operator

    Ruby’s syntax defines the comparison operators ==, ===, <=>, <, <=, >, >=, =~. All of these operators are implemented by methods. Traditionally, Ruby also uses the standard method EQL? And equal? . Where == and =~ have opposite forms! = and! ~

  • If statement

    The if statement is the most basic condition statement of the form:

    ifCondition 1thenProcessing 1 Elseif condition 2thenProcessing 2 Elseif condition 3thenTo deal with 3elseDeal with 4 endCopy the code

    You can omit then

  • Unless the statement

    Unless is the opposite of if, with the form:

    Unless conditionsthenDeal with 1elseDeal with 2 endCopy the code

    You can omit then

  • The if and unless decorators

    If and unless can be written after the code you want to execute, as follows

    puts "a > b" if a > b
    Copy the code

    When using modifiers, pay attention to program readability

  • Ternary operator

    The ternary operator is if… Else short form

    Conditions? Process 1: Process 2Copy the code
  • A case statement

    Using a case statement makes the program simpler and easier to understand when there is only one comparison object that performs different processing depending on the value of the object

    caseThe comparison object when is 1thenProcess 1 when value 2thenProcess 2 when value 3thenTo deal with 3elseDeal with 4 endCopy the code

    You can omit then

cycle

  • Times method

    The Times method makes it easy to simply perform processing a certain number of times

    Number of cycles. TimesdoWant the loop to handle endCopy the code

    do… The end part can be used with {… } instead of

    Times {desired loop processing}Copy the code

    The Times method also tells you the current number of cycles in the block

    5.times do |i|
      puts "Loop #{I}"
    end
    Copy the code
  • For statement

    For is not a method, but a loop control statement provided by Ruby. The form is as follows:

    forvariableinStart value.. The end valuedoWant the loop to handle endforvariableinobjectdoWant the loop to handle endCopy the code

    You can omit the do

    sum = 0
    for i in1.. 5 sum = sum + i end puts sum names = ["awk"."Perl"."Python"."Ruby"]
    for name in names
      puts name
    end
    Copy the code
  • While statement

    No matter what type of loop, a while statement can do the job. The structure of a while statement is as follows:

    whileconditionsdoWant the loop to handle endCopy the code

    You can omit the do

    i = 1
    while i < 3
      puts i
      i += 1
    end
    Copy the code
  • Until the statement

    Until is the opposite of while. The structure of the until statement is exactly the same as that of the while statement, except that the condition judgment is reversed and the loop is executed only when the condition is not met

    Until conditionsdoWant the loop to handle endCopy the code

    You can omit the do

    sum = 0
    i = 1
    until sum >= 50
      sum += i
      i += 1
    end
    puts sum
    Copy the code
  • Each method

    The each method fetches objects from a collection of objects one by one, much like a for loop fetches elements from an array

    Object.do| | variable hope circulation processing end object. Each {| | variable hope circulation processing}Copy the code

    Inside Ruby, the for statement is implemented using the each method. So you can use an object of the each method, and you can also specify a loop object for the for statement

    sum = 0 (1.. 5).eachdo |i|
      sum = sum + i
    end
    puts sum
    Copy the code
  • Loop method

    There is also a looping method, where there is no condition to terminate the loop, but just loop processing

    loop doWant the loop to handle endCopy the code

    A program accidentally executes an infinite loop, which can be forcibly terminated by Ctrl + C

    loop do
      puts "Ruby"
    end
    Copy the code
  • Cycle control

    Break Terminates the processing and breaks the loop

    Next skips to the next loop

    Redo was repeated under the same conditions. Rarely used in general

methods

  • call

    Simple method calls

    Object. Method name (parameter 1, parameter 2... , the parameter n)Copy the code

    Objects are also called receivers. In the object-oriented world, calling a method is called “sending a message to an object.” The result of the call is “the object receives the message.” In other words, a method call is a process in which several parameters are sent to an object along with a message

    Method calls with blocks

    Object. Method name (parameter,...)do| variables 1, 2,... | block content end object. Method name (parameter,...) {| variables 1, 2,... } | piece of contentCopy the code

    | to | in the specified variables called blocks. During block execution, block variables are passed inside the block by methods

    5.times do |i|
      puts i
    end
    Copy the code
  • define

    Definition of general methods

    Def method name (arguments 1, 2... , argument n) the processing end that you want to executeCopy the code

    We can specify the return value of a method with a return statement

    returnCopy the code

    Usually the result of the last expression of a method becomes the return value of the method, so you can omit the return statement

    With the yield keyword we can define methods with blocks

    def myloop
      while true
        yield
      end
    end
    
    num = 1
    myloop do
      puts "num is #{num}"
      break if num > 10
      num *= 2
    end
    Copy the code

    A method with an indeterminate number of arguments can be defined by the * variable name. Arguments can also be specified as an array of *

    def foo(*args)
      args
    end
    
    p foo(1, 2, 3)      => [1, 2, 3]
    p foo(*[4, 5, 6])   => [4, 5, 6]
    Copy the code

    Defines methods that take keyword arguments

    Def method name (parameter 1: the value of parameter 1, parameter 2: the value of parameter 2,...) The processing end that you want to executeCopy the code

    The parameter value can be omitted if there is no default value. We can also use the form **args to receive undefined parameters

    def volume(x:, y: 2, z: 4, **args)
      [x, y, z, args]
    end
    
    p volume(x: 2, y: 3)        => [2, 3, 4, {}]
    p volume({x: 3, k: 5})      => [3, 2, 4, {:k=>5}]
    Copy the code

Classes and objects

  • Class and inheritance

    Classes represent classes of objects, and objects in Ruby must all belong to a class. Creating a new class by extending a defined class is called inheritance.

    Class Class name [< superclass name] Class definition endCopy the code

    The first letter of a class must be capitalized. The Initialize method in the class is special. When the new method is used to generate a new object, the Initialize method is called and the parameters of the new method are passed to the Initialize method unchanged

    class HelloWrold
      def initialize(myname = "Ruby")
        @name = myname
      end
    end
    
    bob = HelloWrold.new("Bob")
    ruby = HelloWrold.new
    Copy the code
  • accessor

    In Ruby, instance variables cannot be directly accessed or modified from outside the object; you need methods to access the inside of the object. Ruby provides easy methods to define attr_reader, attr_writer, and attr_accessor

    Attr_reader :name read-only (define the name method)

    Attr_writer :name only writes (define name= method)

    Attr_accessor :name Reads and writes (define both methods)

  • Class method

    Methods whose recipients are the classes themselves are called class methods

    The class << class name method defines the end def class name. Method name (parameter,...) endCopy the code

    Four definitions are shown below

    class << HelloWorld
      def hello(name)
        puts "#{name} said hello."
      end
    end
    
    HelloWorld.hello("John")        => John said hello.
    
    class HelloWorld
      class << self
        def hello(name)
          puts "#{name} said hello."
        end
      end
    end
    
    HelloWorld.hello("Allen")       => Allen said hello.
    
    def HelloWorld.hello(name)
      puts "#{name} said hello."
    end
    
    HelloWorld.hello("Amber")       => Amber said hello.
    
    class HelloWorld
      def self.hello(name)
        puts "#{name} said hello."
      end
    end
    
    HelloWorld.hello("Chloe")       => Chloe said hello.
    Copy the code
  • Class variables and constants

    Class variables are shared by all instances of the class, similar to constants

    class HelloWorld
      Version = "1.0"
      @@count = 0
    
      def self.count
        @@count
      end
    
      def initialize(myname = "Ruby")
        @name = myname
      end
    
      def hello
        @@count += 1
        puts "Hello, world. I am #{@name}."
      end
    end
    
    bob = HelloWorld.new("Bob")
    alice = HelloWorld.new("Alice")
    ruby = HelloWorld.new
    
    p HelloWorld.count      => 0
    bob.hello
    alice.hello
    ruby.hello
    p HelloWorld.count      => 3
    Copy the code
  • Limiting method calls

    Public exposes the method externally in the form of an instance method

    Private can only call the method as the default receiver

    Protected This method can be called as an instance method when in the same class

    Class Point attr_accessor :x, :y protected :x=, :y= def initialize(x=0.0, y=0.0) @x, @y = x, y end public def swap(other) tmp_x, tmp_y = @x, @y @x, @y = other.x, other.y other.x, other.y = tmp_x, tmp_yreturnSelf end p1 = point.new (1.0, 2.0) p2 = point.new (3.0, 4.0) p [p2.x, p2.y] p [p2.x, p2.y] p1. Swap (p2) p [p2.x, p2.y] p1. p1.y] p [p2.x, p2.y]Copy the code
  • Alias with undef

    Sometimes we want to alias an existing method, in which case we need to use the alias method

    aliasThe alias Formerly known asaliasAlias: original nameCopy the code

    Undef is used to delete defined methods

    Undef Method name undef: method nameCopy the code
  • The module

    Modules are one of Ruby’s features

    Module The module defines endCopy the code

    Modules cannot have instances, and modules cannot be inherited. If you want to expose methods as module functions for external use, you need to use the module_function method

    module HelloModule
      Version = "1.0"
    
      def hello(name)
        puts "Hello, #{name}"End module_function :hello end p HelloModule::Version => 1.0 HelloModule."Alice"Alice include HelloModule Version => 1.0 Hello ("Alice")              => Hello, Alice
    Copy the code

    You can use mix-ins to Mix modules into classes. Use include when defining a class, so that methods and constants in a module can be used by the class

    module M
      def meth
        "meth"
      end
    end
    
    class C
      include M
    end
    
    c = C.new
    p c.meth        => meth
    Copy the code

Error and exception handling

  • Exception handling

    Ruby exceptions are objects of Exception or a subclass of it and are written as follows:

    Begin Indicates the processing that an exception may occur. Rescue Indicates the processing end when an exception occursCopy the code

    In Ruby, exceptions and their associated information are handled as objects. The exception object can be obtained by specifying the variable name after rescue

    Begin Indicates that exceptions may occur rescue => End indicates that exceptions occur in variables that reference abnormal objectsCopy the code

    The exception object method has the class exception type, the Message exception message, and the backtrace exception location

  • post-processing

    The processing that you want to perform regardless of whether an exception occurs is defined in Ruby using the ensure keyword

    Begin Process that may occur rescue => Process that occurs when a variable is abnormal Ensure Process that is performed regardless of whether an exception occurs EndCopy the code
  • retry

    After retry is used in rescue, the operations following begin are repeated

    begin
      io = File.open(file)
    rescue
      sleep 10
      retry
    end
    Copy the code
  • Rescue the modifier

    Rescue, like the if and unless modifiers, has a corresponding modifier

    Expression 1 rescue expression 2Copy the code

    If an exception occurs in expression 1, the value of expression 2 becomes the value of the entire expression

    n = Integer(val) rescue 0
    Copy the code
  • Abnormal complement

    If the scope of exception handling is the entire processing of a method, that is, programs within the entire method use BEGIN… If end is enclosed, begin and end can be omitted, and programs of Rescue and Ensure can be directly written

    The def foo class defines rescue => ensure endCopy the code

    When multiple types of exceptions exist and need to be handled according to the types of exceptions, multiple rescues can be used to handle them separately

    Begin Handle exceptions that may occur rescue Exception1, Exception2 => Variable Exception1 Rescue Exception3 => Variable Exception2 Rescue Handle exceptions other than the preceding exceptions endCopy the code
  • Actively throwing an exception

    Raise message – Raises a RuntimeError exception and sets the string as the message in the newly generated exception object

    Raise Exception class – Raises the specified exception

    Raise Exception class, information – Raises the specified exception and sets the string of information in the newly generated exception object

    Raise – Raises a RuntimeError outside rescue. When called from rescue, the exception that last occurred is thrown again ($!).

Block (block)

A block is a collection of processes that can be passed along with arguments when a method is called

  • Control block execution

    Like loops, blocks use break, Next, and redo as process control

  • Encapsulate a block as an object

    As mentioned above, you can use the yield keyword when executing a block in a method that receives a block. Ruby can also treat blocks as objects. Once you treat a block as an object, you can execute the block somewhere other than the method that received it, or hand it off to another method for execution

    To manipulate a block as an object, we need the Proc object. A typical way to define a Proc object is to call the blocked method proc.new. The program defined in the block is not executed until the call method of the Proc object is called

    hello = Proc.new do |name|
      puts "Hello, #{name}"
    end
    
    hello.call("World")
    hello.call("Ruby")
    Copy the code

    When defining a method, Ruby automatically wraps the block passed in when the method is called as a Proc object if the trailing argument is an & argument

    def total(from, to, &block)
      result = 0
      from.upto(to) do |num|
        if block
          result += block.call(num)
        else
          result += num
          end
      end
      return result
    end
    
    p total(1, 10)                      => 55
    p total(1, 10) {|num| num ** 2}     => 385
    Copy the code
  • scope

    Namespaces inside the block are shared with namespaces outside the block. Local variables defined outside the block can continue to be used within the block. Well! In short, this makes it easy for Ruby to implement functional closures.

    def counter
      cnt = 0
      Proc.new do
        cnt += 1
      end
    end
    
    c1 = counter
    c2 = counter
    
    c1.call         => 1
    c1.call         => 2
    c1.call         => 3
    c2.call         => 1
    c2.call         => 2
    Copy the code

resources

  • Ruby’s official website
  • Ruby documentation

The original link