Viết code đẹp trong Ruby (Phần 1)
1. Giới thiệu Như trên tiêu đề của bài viết thì hôm nay tôi sẽ giới thiệu tới các bạn một số qui tắc viết code đẹp trong Ruby. Đã có khá nhiều các bài viết trên các trang mạng nói về đề tài phong cách lập trình và tư duy viết code đẹp, hơn nữa vấn đề này cũng thuộc về phong cách lập trình của mỗi ...
1. Giới thiệu
Như trên tiêu đề của bài viết thì hôm nay tôi sẽ giới thiệu tới các bạn một số qui tắc viết code đẹp trong Ruby. Đã có khá nhiều các bài viết trên các trang mạng nói về đề tài phong cách lập trình và tư duy viết code đẹp, hơn nữa vấn đề này cũng thuộc về phong cách lập trình của mỗi lập trình viên nhưng vẫn có những qui tắc chung trong giới coder để sao cho code dễ đọc, dễ viết và nhìn đẹp hơn. Sau đây tôi chỉ giới thiệu 15 qui tắc code trong ngôn ngữ Ruby cực kì kinh điển mà đôi khi lập trình viên không để ý nhưng nó lại cực kì quan trọng bởi vì nó đã được cả cộng đồng lập trình Ruby tuân theo. Để đạt được những qui tắc này thì cộng đồng lập đã trải qua một quá trình đấu tranh lâu dài để bài trừ những đoạn code xấu. Ở đây tôi sẽ tổng hợp lại và chia theo một số tiêu chí để các bạn dễ theo dõi. Và hãy nhớ đây chỉ là style trong code Ruby nhé!
2. Cách dùng khoảng trắng
- KHÔNG DÙNG khoảng trắng sau (, [ và trước ], ). DÙNG khoảng trắng quanh { và trước } trừ trường hợp nhúng biến vào string
#bad some( arg ) [ 1, 2, 3 ].each{|x| puts x} {one: 1, two: 2} "From: #{ user.first_name }, #{ user.last_name }" #good some(arg) [1, 2, 3].each { |x| puts x } { one: 1, two: 2 } "From: #{user.first_name}, #{user.last_name}"
Lưu ý đối với các ngoặc nhọn { và } là nó được dùng cho cả block, hash và nhúng biến vào string.
- KHÔNG DÙNG khoảng trắng sau dấu chấm than !
#bad ! something #good !something
- KHÔNG DÙNG khoảng trắng khi khai báo khoảng (khoảng)
#bad (1 .. 5) #good (1..5)
- KHÔNG DÙNG khoảng trắng giữa tên hàm và dấu ngoặc mở (
#bad def something (x) end #good def something(x) end
-
KHÔNG ĐỂ khoảng trắng thừa ở những dòng code cuối cùng
-
DÙNG khoảng trắng trước và sau toán tử(ngoại trừ toán tử mũ) , sau dấu phẩy, dấu hai chấm và dấu chấm phẩy. Khoảng trắng có thể (hầu hết) là không bắt buộc, nhưng nó sẽ giúp code dễ đọc, dễ viết hơn.
#bad a=1 a=b+c a = [1,2,3] e = M * c ** 2 #good a = 1 a = b + c a = [1, 2, 3] e = M * c**2
3. Các đặt tên hàm, tên biến, tên phương thức
- Dùng tiếng Anh để đặt tên, không dùng các kí tự đặc biệt không thuộc bảng mã ascii
# bad заплат = 1_00 # dùng các kí tự không thuộc bảng mã ascii zazazaza = 1_00 # không phải tiếng anh # good price = 1_00
- Dùng snake_case cho tên phương thức, biến và nhãn (symbol).
# bad :'some variable' :SomeVariable :someVariable someVar = 5 def someMethod # something end def SomeMethod # something end # good :some_variable def some_method # something end
-
Dùng snake_case cho tên file và tên thư mục, vd: views/hello_world/hello_world.rb.
-
Dùng CamelCase cho tên class và tên module. (viết hoa các từ viết tắt sau HTTP, RFC, XML)
# bad class Someclass # some code end class Some_Class # some code end class SomeXttp # some code end class HttpSomething # some code end # good class SomeClass # some code end class SomeHTTP # some code end class HTTPSomething # some code end
- Mỗi file chỉ nên có một class/module. Tên của file chính là tên của class/module nhưng thay PascalCase thành snake_case.
Ví dụ Tên file là item_comment.rb thì tên class/module bên trong sẽ đặt là
class ItemComment #something end
- Dùng SCREAMING_SNAKE_CASE cho hằng số.
# bad ConstNumber = 2 const_number = 2 # good CONST_NUMBER = 2
- KHÔNG NÊN đặt tiền tố cho tên phương thức với các động từ bổ trợ như is, does, hay can. Những từ này không cần thiết và nghĩa quá chung chung, không đồng nhất với các phương thức boolean của ngôn ngữ: empty? hay include?.
# bad class Cake def is_small? true end def can_play_football? true end def does_like_pizza? false end end # good class Cake def small? true end def football_player? true end def likes_pizza? false end end
- Nếu có phương thức nguy hiểm thì nên có thêm phương thức an toàn.
# bad class Animal def update! end end # good class Animal def update end end # good class Animal def update! end def update end end
4. Cách trình bày bố cục
- Nên sử dụng tabsize bằng 2 khoảng trắng. Nếu bạn cùng sublime text thì có thể setting tabsize và một số setting khác như sau:
Ở thanh menu chọn Preferences -> Setting - Distraction Free rồi thêm đoạn code sau vào file và lưu lại.
{ "ensure_newline_at_eof_on_save": true, "font_size": 9, "highlight_line": true, "ignored_packages": [ "Vintage" ], "rulers": [ 80 ], "show_encoding": true, "show_line_endings": true, "tab_size": 2, "translate_tabs_to_spaces": true, "trim_trailing_white_space_on_save": true }
=> Khi sử dụng tabsize là 2 thì sẽ dễ nhìn hơn và tiết kiệm dòng code hơn.
- Không dùng dấu chấm phẩy ; để ngăn cách các câu lệnh và biểu thức, mà hãy viết mỗi câu 1 dòng.
# bad puts 'foobar'; # Thừa dấu chấm phẩy puts 'foo'; puts 'bar' # hai câu lệnh trên cùng 1 dòng # good puts 'foobar' puts 'foo' puts 'bar' puts 'foo', 'bar' # câu lệnh này sẽ tự tách làm hai lệnh `puts`
- Tránh kiểu viết gom nhiều phương thức vào một dòng. Mặc dù ở một vài nơi nó vẫn được sử dụng, có một vài điểm đặc thù khiến người ta cảm thấy khó chịu khi gặp nó. Dù sao vẫn không nên viết nhiều hơn một biểu thức, câu lệnh trên một dòng.
# bad def method_name; something; something_else; end # okish def some_method() body end # đúng cú pháp nhưng khó đọc hơn # good def some_method body end
- Cặp if, else hoặc when, case thụt đầu dòng cùng cấp. Style này được khuyến khích dùng trong cả "The Ruby Programming Language" và "Programming Ruby".
# bad case when some_condition #do something when some_condition #do something when some_condition #do something else #do something end # good case when some_condition #do something when some_condition #do something when some_condition #do something else #do something end
- KHÔNG DÙNG dấu phẩy , sau tham số cuối cùng khi khai báo phương thức, đặc biệt khi những tham số không nằm trên những dòng riêng biệt.
# bad some_method( blue, red, black, ) # bad some_method(blue, red, black, ) # good some_method(blue, red, black)
Thêm một dòng trống giữa các phương thức, và các nhóm xử lý logic.
def some_method key = "#{CATCH_KEY}#{id}" Price.all.pluck(:id) data.result end def some_method result end
- Với cách gọi phương thức nhiều lần liên tiếp, có hai kiểu thông dụng, kiểu nào cũng được cả: . ở đầu dòng mới (Cách 1) hoặc . ở cuối dòng cũ (Cách 2). Mặc dù dùng kiểu nào thì cũng nên dùng nhất quán một kiểu.
#Cách 1 one.two.three .four #Cách 2 one.two.three. four
Xem thêm về cuộc thảo luận chọn cách nào: tại đây
Thứ tự viết trong một file
Các phần trong một file nên viết theo thứ tự sau
class Person # Đầu tiên là extend và include extend SomeModule include AnotherModule # tiếp theo là inner classes CustomErrorKlass = Class.new(StandardError) # tiếp theo là khai báo hằng số SOME_CONSTANT = 20 # tiếp đến attribute macros attr_reader :name # followed by other macros (if any) validates :name # public class methods are next in line def self.some_method end # initialization goes between class methods and other instance methods def initialize end # followed by other public instance methods def some_method end # protected and private methods are grouped near the end protected def some_protected_method end private def some_private_method end end
5. Lời kết và tài liệu tham khảo
Ở phần này tôi đã giới thiệu tới các bạn một số style viết code cơ bản trong ruby bao gồm các phần về bố cục. Ở phần tiếp theo tôi sẽ tiếp tục giới thiệu tới các bạn các style sâu hơn về logic và syntax. Rất mong bài viết này sẽ hữu ích đối với bạn đọc
Tool
Rails có gem Rubocop là một Ruby code style checker các lỗi cơ bản khi viết code, bạn có thể thêm gem này vào project của mình và tùy chỉnh các settings Rubocop