It has been nearly two years since we used Github in the Global Personals project and following Github Flow. During this period, we submitted thousands of pull requests at a high frequency. Although there were not many suggestions and ideas on how to improve or improve the program, however, I still have gained such extensive and valuable experience. There are some suggestions related to the project and a lot of Ruby development tips that can be shared within the team.
I am worried that I will forget the precious skills and experience I have learned from this project. So I picked out the best and most valuable part and shared it with you, at the same time, we made a small expansion. Everyone has their own way of working and style, so I will explain it to you in a concise and clear way. Not every part of the content is new for everyone, but I hope you will get something more or less here.
I divide the article into several pieces to avoid reading 5000 words in one breath and classifying them as several parts for reference.
Let's enter the first part.
Block Blocks)
Code blocks are a very important part of Ruby and are widely used everywhere. If you are not using it, you will find that many people use methods to associate code blocks, or even make the code structure clearer.
A code block has three main functions: looping, setup and teardown, and callbacks or deferred action ).
The following example demonstrates how to use a code block to output the Fibonacci tangent sequence cyclically. It uses block_given? Method to Determine whether a code block is associated; otherwise, an enumerator is returned from the current method.
The yield keyword is used to execute a code block in a method. Its parameters are passed to the code block. After the code block is executed, the call method is returned and the next line of code is executed. The Return Value of the method is the final Fibonacci tangent before the maximum number (max.
- def fibonacci(max=Float::INFINITY)
- return to_enum(__method__, max) unless block_given?
- yield previous = 0
- while (i ||= 1) < max
- yield i
- i, previous = previous + i, i
- end
- previous
- end
-
- fibonacci(100) {|i| puts i }
In the next example, the Operation Code such as setting, destruction, and error handling is put into the method, and the main logic of the method is put into the code block. In this way, the sample code does not need to be repeated in multiple places. In addition, when you need to change the error handling code, you only need to make a few modifications.
The returned result of the yield statement, that is, the return value of the code block, is saved to a local variable. In this way, the execution result of the code block can be used as the return value of the method.
- require "socket"
-
- module SocketClient
- def self.connect(host, port)
- sock = TCPSocket.new(host, port)
- begin
- result = yield sock
- ensure
- sock.close
- end
- result
- rescue Errno::ECONNREFUSED
- end
- end
-
- # connect to echo server, see next example
- SocketClient.connect("localhost", 55555) do |sock|
- sock.write("hello")
- puts sock.readline
- end
The yield keyword is not used in the next example. Here, there is another way to use a code block: Use '&' as the prefix of the last parameter of the method, and save the associated code block as a Proc object to this parameter. The Proc object has a call instance method that can be used to execute code blocks. parameters passed to the call method are used as parameters of the code block. In this example, you can save the code block as the most callback for later execution, or perform delayed operations as needed.
- require "socket"
-
- class SimpleServer
- def initialize(port, host="0.0.0.0")
- @port, @host = port, host
- end
-
- def on_connection(&block)
- @connection_handler = block
- end
-
- def start
- tcp_server = TCPServer.new(@host, @port)
- while connection = tcp_server.accept
- @connection_handler.call(connection)
- end
- end
- end
-
- server = SimpleServer.new(5555)
- server.on_connection do |socket|
- socket.write(socket.readline)
- socket.close
- end
- server.start
Range Ranges)
Intervals are also common in Ruby code. Generally, intervals are in the form of (0 .. 9), which contains all numbers between 0 and 9, including 9. There is also another form (0... 10), contains all numbers between 0 and 10, excluding 10, that is, and the previous form contains all numbers between 0 and 9, including 9. This form is not common, but sometimes it is very useful.
Sometimes you will see code like this:
- random_index = rand(0..array.length-1)
Use the interval that does not contain the end will be more neat:
- random_index = rand(0...array.length)