Coder Social home page Coder Social logo

dereknguyen269 / ruby-style-guide-vietnamese Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 0.0 206 KB

Airbnb's Ruby Style Guide - Vietnamese Version

Home Page: https://github.com/airbnb/ruby

ruby-style-guide ruby ruby-clean-code clean-code ruby-style ruby-clean-code-vietnamese ruby-style-guide-vietnamese

ruby-style-guide-vietnamese's Introduction

Airbnb Ruby Style Guide - Vietnamese (Tiếng Việt)

Các nội dung mà mình dịch sẽ chỉ dịch những phần nào dễ hiểu nhất, còn từ hay đoạn nào dịch ra sẽ nghe rất là kì mình sẽ để nguyên.

Nội Dung

Đây là toàn bộ bài viết được dịch từ Airbnb's Ruby Style Guide.

Bài viết này được lấy cảm hứng từ Github's guideBozhidar Batsov's guide.

Airbnb cũng đang hỗ trợ cho một JavaScript Style Guide.

Mục Lục

  1. Khoảng trắng/ Khoảng cách 1. Thụt đầu dòng 1. Trong cùng một dòng 1. Dòng mới
  2. Chiều dài của dòng
  3. Chú thích 1. Chú thích cho File/class-level 1. Chú thích cho Function 1. Chú thích trong block và trong dòng 1. Dấu chấm câu, lỗi chính tả và ngữ pháp 1. Chú thích TODO 1. Commented-out code
  4. Các phương thức (Methods) 1. Các phương thức định nghĩa (Method definitions) 1. Các cách gọi phương thức (Method calls)
  5. Biểu thức điều kiện (Conditional Expressions) 1. Từ khóa điều kiện (Conditional keywords) 1. Ternary operator
  6. Cú pháp (Syntax)
  7. Naming
  8. Các lớp (Classes)
  9. Trường hợp ngoại lệ (Exceptions)
  10. Collections
  11. Chuỗi (Strings)
  12. Regular Expressions
  13. Percent Literals
  14. Rails 1. Scopes
  15. Be Consistent
  16. Translation

Khoảng trắng / Khoảng cách

Thụt đầu dòng

  • Sử dụng phím tab với 2 khoảng trắng thụt vào[link]

  • Thụt đầu dòng cho when cùng cấp như case. [link]

    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
    
    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
  • Căng lề cho function parameters như trên cùng một hàng ngang hoặc hàng dọc [link]

    # bad
    def self.create_translation(phrase_id, phrase_key, target_locale,
                                value, user_id, do_xss_check, allow_verification)
      ...
    end
    
    # good
    def self.create_translation(phrase_id,
                                phrase_key,
                                target_locale,
                                value,
                                user_id,
                                do_xss_check,
                                allow_verification)
      ...
    end
    
    # good
    def self.create_translation(
      phrase_id,
      phrase_key,
      target_locale,
      value,
      user_id,
      do_xss_check,
      allow_verification
    )
      ...
    end
  • Thọc đầu dòng cho các line tiếp theo của cùng một biểu thức boolean[link]

    # bad
    def is_eligible?(user)
      Trebuchet.current.launch?(ProgramEligibilityHelper::PROGRAM_TREBUCHET_FLAG) &&
      is_in_program?(user) &&
      program_not_expired
    end
    
    # good
    def is_eligible?(user)
      Trebuchet.current.launch?(ProgramEligibilityHelper::PROGRAM_TREBUCHET_FLAG) &&
        is_in_program?(user) &&
        program_not_expired
    end

Trong cùng một dòng

  • Không bao giờ có dấu khoảng cách/khoảng trắng (Never leave trailing whitespace). [link]

  • Khi chú thích cho code của bạn trên cùng một dòng cần phai có dấu khoảng cách giữa code và chú thích của bạn. [link]

    # bad
    result = func(a, b)# we might want to change b to c
    
    # good
    result = func(a, b) # we might want to change b to c
  • Sử dụng các khoảng trắng trước và sau operators; sau dâu phẩy, dấu hai chấm, và dấu phẩy; trước và sau { cũng như }. [link]

    sum = 1 + 2
    a, b = 1, 2
    1 > 2 ? true : false; puts 'Hi'
    [1, 2, 3].each { |e| puts e }
  • Không bao giờ có khoảng cách trước dấu phẩy [link]

    result = func(a, b)
  • Không nên có khoảng trắng trong block parameter pipes. Hoặc khoảng trắng giữa các parameters trong một block. Hoặc có thêm một khoảng trắng ở bên ngoài block parameter pipes. [link]

    # bad
    {}.each { | x,  y |puts x }
    
    # good
    {}.each { |x, y| puts x }
  • Không nên có khoảng trắng giữa !argument[link]

    !something
  • Không có khoảng trắng sau (, [ hoặc trước ], ). [link]

    some(arg).other
    [1, 2, 3].length
  • Không nên có khoảng trắng sau { hoặc trước } khi viết một biến trong một chuỗi(string)[link]

    # bad
    var = "This #{ foobar } is interpolated."
    
    # good
    var = "This #{foobar} is interpolated."
  • Không sử dụng các khoảng trống thừa trong range literals.[link]

    # bad
    (0 ... coll).each do |item|
    
    # good
    (0...coll).each do |item|

Dòng mới

  • Nếu có nhiều điều kiện cho mệnh đề if thì nên chia ra thành nhiều dòng để giúp phân biệt rõ ràng hơn. [link]

    if @reservation_alteration.checkin == @reservation.start_date &&
       @reservation_alteration.checkout == (@reservation.start_date + @reservation.nights)
    
      redirect_to_alteration @reservation_alteration
    end
  • Thêm một dòng mới sau điều kiện, block, các trường hợp case[link]

    if robot.is_awesome?
      send_robot_present
    end
    
    robot.add_trait(:human_like_intelligence)
  • Không nên có các dòng trống giữa các indentation khác nhau (như giữa class hoặc module với các method bên trong nó). [link]

    # bad
    class Foo
    
      def bar
        # body omitted
      end
    
    end
    
    # good
    class Foo
      def bar
        # body omitted
      end
    end
  • Nên chỉ có một dòng trống giữa các method với nhau[link]

    def a
    end
    
    def b
    end
  • Sử dụng một dòng trống duy nhất để phân biệt các logic cho từng bước. [link]

    def transformorize_car
      car = manufacture(options)
      t = transformer(robot, disguise)
    
      car.after_market_mod!
      t.transform(car)
      car.assign_cool_name!
    
      fleet.add(car)
      car
    end
  • Cuối mỗi file nên chỉ có một dòng trống là đủ. [link]

Chiều dài của dòng

  • Độ dài của dòng code sao cho có thể dễ dàng đọc và hiểu được. Tốt nhất nên ít hơn 100 kí tự.  (lý do) [link]

Chú thích

Việc viết chú thích cho code là điều quan trọng và cần phải làm, điều đó sẽ giúp người khác dễ hiêu hơn. Đây là những qui tắc bạn cần chú thích và chú thích ở đâu. Nhưng bạn phải nhớ: chú thích là quan trọng, code tốt nhất như là có một tài liệu sẵn (the best code is self-documenting). Đặt tên các kiểu và biến dễ hiểu thì sẽ tốt hơn bạn phải chú thích thêm ở sau đó Khi bạn viết chú thích bạn hãy xem mình như một nhà viết sách, những người kế tiếp cần phải hiểu được code của bạn (Be generous — the next one may be you!)

Google C++ Style Guide

Các phần này được trích từ C++Python style guides.

Chú thích cho File/class-level

Mỗi định nghĩa cho một class nên có những chú thich để mô tả nó làm những gì và sử dụng nó như thế nào.

Một file có chứa nhiều class hay không có class nào cũng nên có chú thích ở đầu của nó

# Automatic conversion of one locale to another where it is possible, like
# American to British English.
module Translation
  # Class for converting between text between similar locales.
  # Right now only conversion between American English -> British, Canadian,
  # Australian, New Zealand variations is provided.
  class PrimAndProper
    def initialize
      @converters = { :en => { :"en-AU" => AmericanToAustralian.new,
                               :"en-CA" => AmericanToCanadian.new,
                               :"en-GB" => AmericanToBritish.new,
                               :"en-NZ" => AmericanToKiwi.new,
                             } }
    end

  ...

  # Applies transforms to American English that are common to
  # variants of all other English colonies.
  class AmericanToColonial
    ...
  end

  # Converts American to British English.
  # In addition to general Colonial English variations, changes "apartment"
  # to "flat".
  class AmericanToBritish < AmericanToColonial
    ...
  end

Các tập tin bao gồm dữ liệu và file config cũng nên có file-level comments

# List of American-to-British spelling variants.
#
# This list is made with
# lib/tasks/list_american_to_british_spelling_variants.rake.
#
# It contains words with general spelling variation patterns:
#   [trave]led/lled, [real]ize/ise, [flav]or/our, [cent]er/re, plus
# and these extras:
#   learned/learnt, practices/practises, airplane/aeroplane, ...

sectarianizes: sectarianises
neutralization: neutralisation
...

Chú thích cho Function

Mỗi function nên có chú thích ở trước để mô tả chức năng và cách sử dụng. Các chú thích mô tả cho function, nó cũng sẽ không nói function đó sẽ làm những gì. Nhìn chung, các chú thích này không mô tả cách các chức năng thực hiện nhiệm vụ của mình. Thay vào đó nên nên cho các chú thích xen kẽ giữa các dòng code.

Mỗi function nên đề cập đến đầu ra và đầu vào là những gì. Trừ khi nó đáp ứng tất cả các tiêu chí sau:

  • Không thể nhìn thấy bên ngoài (not externally visible)
  • rất ngắn (very short)
  • rõ ràng (obvious)

Bạn có thể sử dụng bất cứ định dạng nào mà bạn muốn. Trong Ruby, 2 tài liệu phổ biến là TomDocYARD. Bạn có thể viết những điều đó một cách súc tích nhất có thể:

# Returns the fallback locales for the_locale.
# If opts[:exclude_default] is set, the default locale, which is otherwise
# always the last one in the returned list, will be excluded.
#
# For example:
#   fallbacks_for(:"pt-BR")
#     => [:"pt-BR", :pt, :en]
#   fallbacks_for(:"pt-BR", :exclude_default => true)
#     => [:"pt-BR", :pt]
def fallbacks_for(the_locale, opts = {})
  ...
end

Chú thích trong Block và trong cùng một dòng

Là nơi có những chú thích cho những phần code phức tạp. Nếu bạn phải giải thích và review code, bạn nên chú thích cho nó ngay bây giờ. Các code operations phức tạp nên có vài dòng chú thích trước khi bắt đầu. Những đoạn code không rõ ràng cũng nên có chú thích ở cuối.

def fallbacks_for(the_locale, opts = {})
  # dup() to produce an array that we can mutate.
  ret = @fallbacks[the_locale].dup

  # We make two assumptions here:
  # 1) There is only one default locale (that is, it has no less-specific
  #    children).
  # 2) The default locale is just a language. (Like :en, and not :"en-US".)
  if opts[:exclude_default] &&
      ret.last == default_locale &&
      ret.last != language_from_locale(the_locale)
    ret.pop
  end

  ret
end

Mặc khác, không bao giờ mô tả cho code. Giả sử người đọc code biết ngôn ngữ đó (mặc dù không phải những gì bạn cố găng làm) tốt hơn so với bạn làm.

Liên quan: không sử dụng một khối gồm nhiều chú thích cho nhiều dòng code bởi vì nó thật sự khó quan sát[link]

# bad
=begin
comment line
another comment line
=end

# good
# comment line
# another comment line

Dấu chấm câu, lỗi chính tả và ngữ pháp

Hãy chú ý đến dấu chấm câu, lỗi chính tả và ngữ pháp, sẽ dễ dàng hơn nếu đọc hiểu tốt các chú thích của bạn.

Các chú thích nên được viết như văn bản tường thuật, có ngắt nghỉ hợp lý. Trong nhiều trường, câu hoàn chỉnh dễ hiểu hơn so với một câu vắn tắt.

Sử dụng dấu chấm phẩy hoặc dấu phẩy hợp lý. Việc đó rất quan trọng để duy trì tính rõ ràng và dễ đọc. Đúng dâu chấm, dấu phẩy và ngữ pháp sẽ giúp bạn diễn đạt vấn đề rõ ràng hơn.

Chú thích cho TODO (Các việc cần làm)

Sử dụng chú thích cho TODO để thay thế các đoạn code khi chúng chưa được viết. Nó cần ngắn gọn và dễ hiểu nhưng không cần quá hoàn hảo.

TODOs should include the string TODO in all caps, followed by the full name of the person who can best provide context about the problem referenced by the TODO, in parentheses. A colon is optional. A comment explaining what there is to do is required. The main purpose is to have a consistent TODO format that can be searched to find the person who can provide more details upon request. A TODO is not a commitment that the person referenced will fix the problem. Thus when you create a TODO, it is almost always your name that is given.

  # bad
  # TODO(RS): Use proper namespacing for this constant.

  # bad
  # TODO(drumm3rz4lyfe): Use proper namespacing for this constant.

  # good
  # TODO(Ringo Starr): Use proper namespacing for this constant.

Commented-out code

  • Never leave commented-out code in our codebase. [link]

Các phương thức

Các phương thức định nghĩa (Method definitions)

  • Sử dụng def với dấu ngoặc đơn khi có parameters. Bỏ qua không dùng ngoặc đươn khi không có parameters.[link]

    def some_method
      # body omitted
    end
    
    def some_method_with_parameters(arg1, arg2)
      # body omitted
    end
  • Không sử dụng arguments mặc định. Thay vào đó hãy dùng các tùy chọn (options)[link]

    # bad
    def obliterate(things, gently = true, except = [], at = Time.now)
      ...
    end
    
    # good
    def obliterate(things, options = {})
      default_options = {
        :gently => true, # obliterate with soft-delete
        :except => [], # skip obliterating these things
        :at => Time.now, # don't obliterate them until later
      }
      options.reverse_merge!(default_options)
    
      ...
    end
  • Tránh các single-line methods. Mặc dù nó cò phần phổ biến, có một vài đặc thù về định nghĩa làm cho việc sử dụng chúng không như mong muốn. [link]

    # bad
    def too_much; something; something_else; end
    
    # good
    def some_method
      # body
    end

Các cách gọi phương thức (Method calls)

Sử dụng dấu ngoặc đơn để gọi phương thức (method):

  • Nếu method trả về giá trị [link]

    # bad
    @current_user = User.find_by_id 1964192
    
    # good
    @current_user = User.find_by_id(1964192)
  • Nếu đối số đầu tiên của method được sử dụng[link]

    # bad
    put! (x + y) % len, value
    
    # good
    put!((x + y) % len, value)
  • Không bao giờ có khoảng cách / khoảng trắng giữa dâu ngoặc đơn và tên method[link]

    # bad
    f (3 + 2) + 1
    
    # good
    f(3 + 2) + 1
  • Không có dấu ngoặc đơn cho method nếu nó không có đối số truyền vào[link]

    # bad
    nil?()
    
    # good
    nil?
  • Nếu method không trả về giá trị hay không quan trả về cái gì thì dấu ngoặc đơn cũng là một lựa chọn nếu có nhiều dòng, nhiều đối số truyền vào. [link]

    # okay
    render(:partial => 'foo')
    
    # okay
    render :partial => 'foo'

Trong cả hai trường hợp:

  • Nếu method chấp nhận đối số truyền vào cuối cùng là hash, không sử dụng { }. [link]

    # bad
    get '/v1/reservations', { :id => 54875 }
    
    # good
    get '/v1/reservations', :id => 54875

Biểu thức điều kiện

Từ khóa điều kiện

  • Không bao giờ sử dụng then cho nhiều dòng if/unless. [link]

    # bad
    if some_condition then
      ...
    end
    
    # good
    if some_condition
      ...
    end
  • Không bao giờ sử dụng do cho nhiều dòng while hoặc until.[link]

    # bad
    while x > 5 do
      ...
    end
    
    until x > 5 do
      ...
    end
    
    # good
    while x > 5
      ...
    end
    
    until x > 5
      ...
    end
  • Các từ khóa and, or, và not đều không khả dungk. Nó chỉ là từ không có giá trị trong ruby. Thay vào đó luôn sử dụng &&, ||, và !. [link]

  • if/unless thì được chấp nhận khi nội dung đơn giản, điều kiện là đơn giản, và chỉ nằm trên một dòng. Nếu không hãy tránh if/unless. [link]

    # bad - this doesn't fit on one line
    add_trebuchet_experiments_on_page(request_opts[:trebuchet_experiments_on_page]) if request_opts[:trebuchet_experiments_on_page] && !request_opts[:trebuchet_experiments_on_page].empty?
    
    # okay
    if request_opts[:trebuchet_experiments_on_page] &&
         !request_opts[:trebuchet_experiments_on_page].empty?
    
      add_trebuchet_experiments_on_page(request_opts[:trebuchet_experiments_on_page])
    end
    
    # bad - this is complex and deserves multiple lines and a comment
    parts[i] = part.to_i(INTEGER_BASE) if !part.nil? && [0, 2, 3].include?(i)
    
    # okay
    return if reconciled?
  • Không bao giờ sử dụng unless với else. [link]

    # bad
    unless success?
      puts 'failure'
    else
      puts 'success'
    end
    
    # good
    if success?
      puts 'success'
    else
      puts 'failure'
    end
  • Tránh dùng unless nhiều điều kiện[link]

      # bad
      unless foo? && bar?
        ...
      end
    
      # okay
      if !(foo? && bar?)
        ...
      end
  • Không sử dụng dấu ngoặc đơn xung quanh if/unless/while. [link]

    # bad
    if (x > 10)
      ...
    end
    
    # good
    if x > 10
      ...
    end

Ternary operator

  • Avoid the ternary operator (?:) except in cases where all expressions are extremely trivial. However, do use the ternary operator(?:) over if/then/else/end constructs for single line conditionals.[link]

    # bad
    result = if some_condition then something else something_else end
    
    # good
    result = some_condition ? something : something_else
  • Use one expression per branch in a ternary operator. This also means that ternary operators must not be nested. Prefer if/else constructs in these cases.[link]

    # bad
    some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
    
    # good
    if some_condition
      nested_condition ? nested_something : nested_something_else
    else
      something_else
    end
  • Avoid multiple conditions in ternaries. Ternaries are best used with single conditions. [link]

  • Avoid multi-line ?: (the ternary operator), use if/then/else/end instead. [link]

    # bad
    some_really_long_condition_that_might_make_you_want_to_split_lines ?
      something : something_else
    
    # good
    if some_really_long_condition_that_might_make_you_want_to_split_lines
      something
    else
      something_else
    end

Cú pháp (Syntax)

  • Không bao giờ dùng for, trừ khi bạn biết chính xác lý do tại sao. Hầu hết các vòng lặp thời gian nên được sử dụng thay thế. for thì thực giống như một phần của each (vì vật bạn đang thêm một cấp gián tiếp), nhưng với một twist - for không giới hạn trong một phạm vi mới (không giôngd each) và các biến được định nghĩa trong nó block sẽ được hiển thị bên ngoài nó.[link]

    arr = [1, 2, 3]
    
    # bad
    for elem in arr do
      puts elem
    end
    
    # good
    arr.each { |elem| puts elem }
  • Prefer {...} tốt hơn do...end cho single-line blocks. Tránh sử dụng {...} cho multi-line blocks (nhiều dòng thì không tốt cho lắm). Luôn dùng do...end cho "kiểm soát vòng lặp" và "định nghĩa phương thức". Avoid do...end when chaining.[link]

    names = ["Bozhidar", "Steve", "Sarah"]
    
    # good
    names.each { |name| puts name }
    
    # bad
    names.each do |name| puts name end
    
    # good
    names.each do |name|
      puts name
      puts 'yay!'
    end
    
    # bad
    names.each { |name|
      puts name
      puts 'yay!'
    }
    
    # good
    names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
    
    # bad
    names.select do |name|
      name.start_with?("S")
    end.map { |name| name.upcase }

    Một số cho rằng multiline chaining sẽ trông tốt hơn với việc dùng {...}, nhưng họ nên tự hỏi nếu chúng có thể thực sự đọc được và nội dung của block có thể được tách ra thành nhiều phương pháp tiện lợi.

  • Use shorthand self assignment operators whenever applicable.[link]

    # bad
    x = x + y
    x = x * y
    x = x**y
    x = x / y
    x = x || y
    x = x && y
    
    # good
    x += y
    x *= y
    x **= y
    x /= y
    x ||= y
    x &&= y
  • Tránh dâu phẩy trong định nghĩa single line class. Không có khoảng trắng / khoảng cách trước dấu phẩy.[link]

    # bad
    puts 'foobar'; # superfluous semicolon
    puts 'foo'; puts 'bar' # two expressions on the same line
    
    # good
    puts 'foobar'
    
    puts 'foo'
    puts 'bar'
    
    puts 'foo', 'bar' # this applies to puts in particular
  • Sử dụng :: chỉ để tham khảo(bao gồm classemodules) và constructors (giống như Array() hoặc Nokogiri::HTML()). Không dùng :: cho phương pháp gọi thông thường.[link]

    # bad
    SomeClass::some_method
    some_object::some_method
    
    # good
    SomeClass.some_method
    some_object.some_method
    SomeModule::SomeClass::SOME_CONST
    SomeModule::SomeClass()
  • Tránh return khi không cần thiết. [link]

    # bad
    def some_method(some_arr)
      return some_arr.size
    end
    
    # good
    def some_method(some_arr)
      some_arr.size
    end
  • Không sử dụng kết quả trả về của = trong câu điều kiện[link]

    # bad - shows intended use of assignment
    if (v = array.grep(/foo/))
      ...
    end
    
    # bad
    if v = array.grep(/foo/)
      ...
    end
    
    # good
    v = array.grep(/foo/)
    if v
      ...
    end
  • Sử dụng ||= để khởi tạo biến. [link]

    # set name to Bozhidar, only if it's nil or false
    name ||= 'Bozhidar'
  • Không dùng ||= để khởi tạo biến boonlean . (Hãy xem xét những gì sẽ xảy ra nếu giá trị hiện tại đã xảy ra được false.)[link]

    # bad - would set enabled to true even if it was false
    enabled ||= true
    
    # good
    enabled = true if enabled.nil?
  • Sử dụng .call chính xác khi gọi lambdas. [link]

    # bad
    lambda.(x, y)
    
    # good
    lambda.call(x, y)
  • Tránh dùng Perl-style các biến đặc biệt (giống như $0-9, $, ... ). Chúng thì khó hiểu và không khuyến khích sử dụng chúng trong bất kì trường hợp. Tên một biến dài nên giống như $PROGRAM_NAME.[link]

  • Khi một method block chỉ có một đối số , và nội dung chỉ gồm đọc một thuộc tính hoặc gọi một phương thức không có đối số, sử dụng cách viết ngăn &:. [link]

    # bad
    bluths.map { |bluth| bluth.occupation }
    bluths.select { |bluth| bluth.blue_self? }
    
    # good
    bluths.map(&:occupation)
    bluths.select(&:blue_self?)
  • Prefer some_method tốt hơn self.some_method khi khi gọi một phương thức hiện tại.[link]

    # bad
    def end_date
      self.start_date + self.nights
    end
    
    # good
    def end_date
      start_date + nights
    end

    Trong ba trường hợp phố biến sau đây, self. là yêu cầu của ngôn ngữ      và là tốt để sử dụng:

    1. Khi xác định một class method: def self.some_method.
    2. left hand side khi gọi một ssignment method, bao gồm cả thuộc tính khi self là một ActiveRecord model: self.guest = user.
    3. Referencing the current instance's class: self.class.

Naming

  • Sử dụng snake_case cho các phương thức và biến. [link]

  • Sử dụng CamelCase cho các class và module. (Giữ các từ viết tắt như HTTP, RFC, XML viết hoa.) [link]

  • Sử dụng SCREAMING_SNAKE_CASE cho các biến cố tĩnh khác nhau.[link]

  • Tên của các predicate methods (Các phương thức có giá trị trả về kiểu boolean) nên kết thúc bằng một dấu chấm hỏi. (i.e. Array#empty?).[link]

  • Tên khả dụng của các "dangerous" methods (các phương thức có thể chỉnh sửa self hoặc đối số, exit!, ...) nên kết thúc với một dấu chấm than. Bang methods should only exist if a non-bang method exists. (Xem nhiều hơn về nó.) [link]

  • Tên của các các biến throwaway _. [link]

    payment, _ = Payment.complete_paypal_payment!(params[:token],
                                                  native_currency,
                                                  created_at)

Classes

  • Avoid the usage of class (@@) variables due to their "nasty" behavior in inheritance. [link]

    class Parent
      @@class_var = 'parent'
    
      def self.print_class_var
        puts @@class_var
      end
    end
    
    class Child < Parent
      @@class_var = 'child'
    end
    
    Parent.print_class_var # => will print "child"

    Như bạn có thể xem tất cả các lớp trong một hệ thống phân cấp lớp thực sự chia sẻ một class variable. Class instance variables should usually be preferred over class variables.

  • Sử dụng def self.method để khởi tạo singleton methods. This makes the methods more resistant to refactoring changes. [link]

    class TestClass
      # bad
      def TestClass.some_method
        ...
      end
    
      # good
      def self.some_other_method
        ...
      end
  • Tránh dùng class << self trừ khi là cần thiết, single accessorsaliased attributes. [link]

    class TestClass
      # bad
      class << self
        def first_method
          ...
        end
    
        def second_method_etc
          ...
        end
      end
    
      # good
      class << self
        attr_accessor :per_page
        alias_method :nwo, :find_by_name_with_owner
      end
    
      def self.first_method
        ...
      end
    
      def self.second_method_etc
        ...
      end
    end
  • Indent the public, protected, and private methods as much the method definitions they apply to. Cần có một dòng trống phía trên và dưới của chúng.[link]

    class SomeClass
      def public_method
        # ...
      end
    
      private
    
      def private_method
        # ...
      end
    end

Trường hợp ngoại lệ (Exceptions)

  • Không sử dụng các ngoại lệ cho dòng điều khiển. [link]

    # bad
    begin
      n / d
    rescue ZeroDivisionError
      puts "Cannot divide by 0!"
    end
    
    # good
    if d.zero?
      puts "Cannot divide by 0!"
    else
      n / d
    end
  • Tránh giải quyết class Exception. [link]

    # bad
    begin
      # an exception occurs here
    rescue Exception
      # exception handling
    end
    
    # good
    begin
      # an exception occurs here
    rescue StandardError
      # exception handling
    end
    
    # acceptable
    begin
      # an exception occurs here
    rescue
      # exception handling
    end
  • Không xác dịnh RuntimeError một cách rõ ràng trong hai đối số của raise. Prefer error sub-classes for clarity and explicit error creation.[link]

    # bad
    raise RuntimeError, 'message'
    
    # better - RuntimeError is implicit here
    raise 'message'
    
    # best
    class MyExplicitError < RuntimeError; end
    raise MyExplicitError
  • Cung cấp một lớp ngoại lệ và một tin nhắn như hai đối số riêng cho raise, thay vì một trường hợp ngoại lệ. [link]

    # bad
    raise SomeException.new('message')
    # Note that there is no way to do `raise SomeException.new('message'), backtrace`.
    
    # good
    raise SomeException, 'message'
    # Consistent with `raise SomeException, 'message', backtrace`.
  • Avoid using rescue in its modifier form. [link]

    # bad
    read_file rescue handle_error($!)
    
    # good
    begin
      read_file
    rescue Errno:ENOENT => ex
      handle_error(ex)
    end

Collections

  • Tiền tố map tốt hơn collect.[link]

  • Tiền tố detect tốt hơn find. The use of find is ambiguous with regard to ActiveRecord's find method - detect makes clear that you're working with a Ruby collection, not an AR object. [link]

  • Tiền tố reduce tốt hơn inject. [link]

  • Tiền tố size tốt hơn length hoặc count cho performance.[link]

  • Prefer literal array and hash creation notation unless you need to pass parameters to their constructors. [link]

    # bad
    arr = Array.new
    hash = Hash.new
    
    # good
    arr = []
    hash = {}
    
    # good because constructor requires parameters
    x = Hash.new { |h, k| h[k] = {} }
  • Ủng họ việc dùng Array#join hơn là Array#*. [link]

    # bad
    %w(one two three) * ', '
    # => 'one, two, three'
    
    # good
    %w(one two three).join(', ')
    # => 'one, two, three'
  • Sử dụng symbols thay vì string như một hash keys. [link]

    # bad
    hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
    
    # good
    hash = { :one => 1, :two => 2, :three => 3 }
  • Sử dụng plain symbols thay vì string symbols khi có thể.[link]

    # bad
    :"symbol"
    
    # good
    :symbol
  • Sử dụng Hash#key? thay vì Hash#has_key?Hash#value? thay vì Hash#has_value?. According to Matz, the longer forms are considered deprecated. [link]

    # bad
    hash.has_key?(:test)
    hash.has_value?(value)
    
    # good
    hash.key?(:test)
    hash.value?(value)
  • Sử dụng nhiều dòng hashes sẽ giúp code của bạn dễ đọc hơn. [link]

    hash = {
      :protocol => 'https',
      :only_path => false,
      :controller => :users,
      :action => :set_password,
      :redirect => @redirect_url,
      :secret => @secret,
    }
  • Sử dụng dấu phẩy trong một Array sẽ nhiều hơn một dòng[link]

    # good
    array = [1, 2, 3]
    
    # good
    array = [
      "car",
      "bear",
      "plane",
      "zoo",
    ]

Strings

  • Chèn các biến vào trong một chuỗi sẽ trông tốt hơn là phải nối các biến lại và kí tự lại với nhau.[link]

    # bad
    email_with_name = user.name + ' <' + user.email + '>'
    
    # good
    email_with_name = "#{user.name} <#{user.email}>"

    Hơn nữa,luôn ghi nhớ thêm vào Ruby 1.9-style. Let's say you are composing cache keys like this:

    CACHE_KEY = '_store'
    
    cache.write(@user.id + CACHE_KEY)

    Prefer string interpolation instead of string concatenation:

    CACHE_KEY = '%d_store'
    
    cache.write(CACHE_KEY % @user.id)
  • Tránh dùng String#+ khi bạn cần xây dựng dữ liệu lớn. Thay vào đó, sử dụng String#<<. Concatenation mutates the string instance in-place and is always faster than String#+, which creates a bunch of new string objects.[link]

    # good and also fast
    html = ''
    html << '<h1>Page title</h1>'
    
    paragraphs.each do |paragraph|
      html << "<p>#{paragraph}</p>"
    end
  • Sử dụng \ ở cuối dòng thay vì dấu + hoặc << để nối chuỗi cho nhiều dòng. [link]

    # bad
    "Some string is really long and " +
      "spans multiple lines."
    
    "Some string is really long and " <<
      "spans multiple lines."
    
    # good
    "Some string is really long and " \
      "spans multiple lines."

Regular Expressions

  • Tránh sử dụng $1-9 nó rất khó để kiểm soát những gì chúng chứa. Tên các group có thể sử dụng thay vào đó. [link]

    # bad
    /(regexp)/ =~ string
    ...
    process $1
    
    # good
    /(?<meaningful_var>regexp)/ =~ string
    ...
    process meaningful_var
  • Luôn cẩn thận với ^$ giống như việc match đầu/cuối của dòng, không kết thúc chuỗi. Nếu bạn muốn match toàn bộ chuỗi: \A\z.[link]

    string = "some injection\nusername"
    string[/^username$/]   # matches
    string[/\Ausername\z/] # don't match
  • Sử dụng x để sửa cho các regexp phức tạp. Việc làm đó sẽ làm cho chúng dễ đọc và ta có thể thêm vào các chú thích. Cẩn thận các khoảng trắng/khoảng cách bị bỏ qua.[link]

    regexp = %r{
      start         # some text
      \s            # white space char
      (group)       # first group
      (?:alt1|alt2) # some alternation
      end
    }x

Percent Literals

  • Prefer parentheses over curly braces, brackets, or pipes when using %-literal delimiters for consistency, and because the behavior of %-literals is closer to method calls than the alternatives.[link]

    # bad
    %w[date locale]
    %w{date locale}
    %w|date locale|
    
    # good
    %w(date locale)
  • Sử dụng %w.[link]

    STATES = %w(draft open closed)
  • Sử dụng %() cho chuỗi là dòng đơn mà yêu cầu cả cả interpolationembedded double-quotes. Cho nhiều chuỗi nhiều dòng.[link]

    # bad - no interpolation needed
    %(<div class="text">Some text</div>)
    # should be '<div class="text">Some text</div>'
    
    # bad - no double-quotes
    %(This is #{quality} style)
    # should be "This is #{quality} style"
    
    # bad - multiple lines
    %(<div>\n<span class="big">#{exclamation}</span>\n</div>)
    # should be a heredoc.
    
    # good - requires interpolation, has quotes, single line
    %(<tr><td class="name">#{name}</td>)
  • Chỉ sử dụng %r cho regular expressions matching nhiều hơn một kí tự '/'.[link]

    # bad
    %r(\s+)
    
    # still bad
    %r(^/(.*)$)
    # should be /^\/(.*)$/
    
    # good
    %r(^/blog/2011/(.*)$)
  • Tránh dùng %x. [link]

    # bad
    date = %x(date)
    
    # good
    date = `date`
    echo = %x(echo `date`)

Rails

  • Khi ngay lập tức quay trở lại sau khi gọi render hoặc redirect_to, thêm return cho dòng tiếp thep, không nằm cùng 1 dòng. [link]

    # bad
    render :text => 'Howdy' and return
    
    # good
    render :text => 'Howdy'
    return
    
    # still bad
    render :text => 'Howdy' and return if foo.present?
    
    # good
    if foo.present?
      render :text => 'Howdy'
      return
    end

Scopes

  • When defining ActiveRecord model scopes, wrap the relation in a lambda. A naked relation forces a database connection to be established at class load time (instance startup). [link]

    # bad
    scope :foo, where(:bar => 1)
    
    # good
    scope :foo, -> { where(:bar => 1) }

Be Consistent

If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around all their arithmetic operators, you should too. If their comments have little boxes of hash marks around them, make your comments have little boxes of hash marks around them too.

The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you're saying rather than on how you're saying it. We present global style rules here so people know the vocabulary, but local style is also important. If code you add to a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Avoid this.

Google C++ Style Guide

Translation

This style guide is also available in other languages:

ruby-style-guide-vietnamese's People

Contributors

akuhn avatar ankane avatar arlandism avatar artofhuman avatar bmorearty avatar carmi avatar chengyin avatar clizzin avatar conzjiang avatar dereknguyen269 avatar devpuppy avatar edg3r avatar emp823 avatar jamesreggio avatar jonatack avatar ljharb avatar lkosak avatar maxjacobson avatar rahul342 avatar roysc avatar sethkrasnianski avatar sjdemartini avatar tay avatar tommydangerous avatar venantius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.