Analysis of Ruby source code layout and programming style, analysis of ruby source code Layout
Use the UTF-8 as the source file encoding.
Each indentation level uses two spaces (also known as soft tabs). Do not use hard tabs
# bad - four spaces def some_method do_something end # good def some_method do_something end
Use Unix-style line breaks. (* Users of BSD, Solaris, Linux, and OSX are covered by default. Windows users must be very careful .)
- \ N is a line feed, LineFeed in English, and 0 Xa in ASCII code.
- \ R is the Carriage Return, Carriage Return in English, and ASCII code is 0xD.
- In windows, enter is \ n \ r, unix is \ n, and mac is \ r.
If you are using Git, you may want to add the following configuration settings to protect your project (avoid) line breaks that spread over Windows:
$ git config --global core.autocrlf true
You do not need to use; To separate statements and expressions. Use this inference-one row uses an expression
# bad puts 'foobar'; # superfluous semicolon puts 'foo'; puts 'bar' # two expression on the same line # good puts 'foobar' puts 'foo' puts 'bar' puts 'foo', 'bar' # this applies to puts in particular
For class definitions without content, try to use the single row class definition form.
# bad class FooError < StandardError end # okish class FooError < StandardError; end # good FooError = Class.new(StandardError)
Avoid single-line methods. Even if it is still welcomed by some people, there are still some odd syntaxes that are easy to make mistakes.
In any case-a row should not exceed one single row method.
# bad def too_much; something; something_else; end # okish - notice that the first ; is required def no_braces_method; body end # okish - notice that the second ; is optional def no_braces_method; body; end # okish - valid syntax, but no ; make it kind of hard to read def some_method() body end # good def some_method body end
The null method is an exception to this rule.
# good def no_op; end
The space next to the operator, after the comma, colon, and semicolon; before {and before}, most spaces may be irrelevant to Ruby interpretation (CODE, but its proper use is the key to making the code readable.
sum = 1 + 2 a, b = 1, 2 1 > 2 ? true : false; puts 'Hi' [1, 2, 3].each { |e| puts e }
The only exception is when exponential operations are used:
# bad e = M * c ** 2 # good e = M * c**2
{And} deserve additional clarification since they are used for block and hash literal volumes and embedding strings in the form of expressions.
The two types of hash literal are acceptable.
# good - space after { and before } { one: 1, two: 2 } # good - no space after { and before } {one: 1, two: 2}
The first one is slightly more readable (and controversial is that it is generally more popular in the Ruby community ).
The second method adds the differences between block and hash visualization.
No matter which row you choose-but it is best to keep it consistent.
Currently, there are two options for Embedded expressions:
# good - no spaces "string#{expr}" # ok - arguably more readable "string#{ expr }"
The first style is extremely popular and we recommend that you move closer to it. Second, on the other hand, (controversial) more readable.
Like hash-select a style and keep it consistent.
There is no space (, [after or],) before.
Some (arg). other [1, 2, 3]. length! No space. # bad! Something # good! Something
The indentation depth of when and case is the same. I know many people will disagree with this, but it is a recognized style in "The Ruby Programming Language" and "Programming Ruby.
# bad case when song.name == 'Misty' puts 'Not again!' when song.duration > 120 puts 'Too long!' when Time.now.hour > 21 puts "It's too late" else song.play end # good case when song.name == 'Misty' puts 'Not again!' when song.duration > 120 puts 'Too long!' when Time.now.hour > 21 puts "It's too late" else song.play end case when song.name == 'Misty' puts 'Not again!' when song.duraton > 120 puts 'Too long!' when Time.now > 21 puts "It's too late" else song.play end
When the result of a conditional expression is assigned to a variable, keep the branch on the same layer.
# bad - pretty convoluted kind = case year when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz' when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end result = if some_cond calc_something else calc_something_else end # good - it's apparent what's going on kind = case year when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz' when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end result = if some_cond calc_something else calc_something_else end # good (and a bit more width efficient) kind = case year when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz' when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end result = if some_cond calc_something else calc_something_else end
Empty rows are used between method definitions and a method is separated by logical segments.
def some_method data = initialize(options) data.manipulate! data.result end def some_methods result end
Avoid a comma in the last parameter of a method call, especially when the parameter is not in another line.
# bad - easier to move/add/remove parameters, but still not preferred some_method( size, count, color, ) # bad some_method(size, count, color, ) # good some_method(size, count, color)
When a default value is assigned to a method parameter, spaces are used on both sides of =:
# bad def some_method(arg1=:default, arg2=nil, arg3=[]) # do something... end # good def some_method(arg1 = :default, arg2 = nil, arg3 = []) # do something... end
Although the first style is recommended for several Ruby books, the second style is more common in practice (and can be more controversial and readable ).
Avoid using the row continuation character \ when you do not need it \. In practice,
Unless used to connect strings, avoid using row continuation characters under any circumstances.
# bad result = 1 - \ 2 # good (but still ugly as hell) result = 1 \ - 2 long_string = 'First part of the long string' \ ' and second part of the long string'
Adopt a consistent multi-row method chain style. There are two popular styles in the Ruby community, both of which are considered good
-. (Option A) and trailing. (option B ).
(Option A) when A chained method call needs to continue in another row, put. In the second row.
# bad - need to consult first line to understand second line one.two.three. four # good - it's immediately clear what's going on the second line one.two.three .four
(Option B) when a chained method call is continued on the other line, put. In the first line to identify the expression to continue.
# bad - need to read ahead to the second line to know that the chain continues one.two.three .four # good - it's immediately clear that the expression continues beyond the first line one.two.three. four
Here we can find a discussion about the advantages of these two alternative styles.
If the span of a method call exceeds one line, alignment their parameters. When the parameter alignment is inappropriate due to the row width limit,
Single indentation is acceptable after the first line.
# starting point (line is too long) def send_mail(source) Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text) end # bad (double indent) def send_mail(source) Mailer.deliver( to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text) end # good def send_mail(source) Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text) end # good (normal indent) def send_mail(source) Mailer.deliver( to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text ) end
Array literals element of the multi-row span.
# bad - single indent menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam'] # good menu_item = [ 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam' ] # good menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
Add underscores to large values to improve their readability.
# bad - how many 0s are there? num = 1000000 # good - much easier to parse for the human brain num = 1_000_000
Use RDoc and its conventions to write API documents. Do not use empty lines to separate annotation blocks and def.
Each line must be within 80 characters.
Avoid trailing spaces.
Do not use block annotations. They cannot start with a blank Guide (= begin must start with the header) and are not as easy to recognize as normal annotations.
# bad == begin comment line another comment line == end # good # comment line # another comment line
Use RDoc and its conventions in the API documentation. Do not add blank lines between the annotation code block and def.
Keep each line less than 80 characters.
Avoid trailing spaces.