45 tips giúp bạn code bá hơn
Bài đăng này đã không được cập nhật trong 8 năm
45 tips khiến bạn code bá hơn
CHÚ Ý 1. Bài viết phục các bạn làm việc trực tiếp với Ruby on Rails.
CHÚ Ý 2. Like và thả tim ủng hộ nếu bài viết có ích với bạn.
Trong nghề lập trình, có những người code rất tốt, nhìn những dòng code của họ thể hiện sự rõ ràng, mạch lạc và có chút “tinh tế” Vậy làm sao để làm được điều đó? Nó không phải là ngày một ngày hai, mà chính là từng kinh nghiệm nhỏ mà bạn phải cóp nhặt trong quá trình làm việc. Và trong bài viết này mình sẽ chia sẻ cùng bạn một số kinh nghiệm code với Ruby on Rails, những kiến thức này được rất nhiều developer sử dụng. Nó như là quy chuẩn, và thậm chí người ta đã làm hẳn 1 gem là rubucop để khiến cho các dự án có chất lượng sản phẩm tốt hơn, code ít bug hơn, rõ ràng hơn, dễ bảo trì hơn ....
Note : bạn có thể sử dụng gem rubocop để hiểu rõ hơn. Ok, chúng ta hãy bắt đầu.
- Sử dụng các dấu () khi định nghĩa hàm có tham số, bỏ qua nếu không có tham số Việc đó giúp cho code của bạn sẽ sáng sủa hơn.
# không nên dùng () với hàm ko có tham số
def some_method()
# body
end
# nên bỏ ()
def some_method
# body
end
# với hàm có tham số không nên bỏ ()
def some_method_with_arguments arg1, arg2
# body
end
# nên dùng
def some_method_with_arguments(arg1, arg2)
# body
end
- Chỉ sử dụng :: cho hằng số tham chiếu, không sử dụng nó cho các phương thức thông thường
# không nên dùng :: cho h
SomeClass::some_method
some_object::some_method
# nên dùng
SomeClass.some_method
some_object.some_method
SomeModule::SomeClass::SOME_CONST
SomeModule::SomeClass()
- Không bao giờ dùng for nếu như bạn không biết chính xác cái mà bạn đang chạy, vì có thể phần tử mà bạn truy cập sẽ nằm ngoài array.
arr = [1, 2, 3]
# không nên dùng for
for elem in arr do
puts elem
end
# nên dùng
arr.each { |elem| puts elem }
bởi vì nếu elem mà nằm ngoài array thì nó sẽ báo lỗi như sau elem #=> NameError: undefined local variable or method `elem'
- Không sử dụng then cho if/unless nhiều dòng
# không dùng
if some_condition then
# body
end
# dùng
if some_condition
# body
end
- Luôn viết điều kiện với if trên cùng 1 dòng
# không nên
if
some_condition
do_something
do_something_else
end
# nên dùng
if some_condition
do_something
do_something_else
end
- Nên sử dụng các toán tử (? thay thế cho if/then/else/end. Bởi vì nó ngắn gọn và dễ hiểu hơn
# không nên
result = if some_condition then something else something_else end
# nên
result = some_condition ? something : something_else
- Với các biểu thức lồng nhau thì nên dùng if/else
# không nên
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
# nên dùng
if some_condition
nested_condition ? nested_something : nested_something_else
else
something_else
end
- Không nên dùng if x: … vì nó đã được bỏ từ Ruby 1.9
# không nên
result = if some_condition: something else something_else end
# nên dùng
result = some_condition ? something : something_else
- Nên tận dụng việc biểu thức if sẽ trả về một kết quả
# không nên
if condition
result = x
else
result = y
end
# nên
result =
if condition
x
else
y
end
- Không bao giờ dùng if x; ….
- Không dùng when x; ….
- Sử dụng when x then … cho trường hợp chỉ có 1 dòng. Chú ý không dùng when x: … vì nó đã bị bỏ từ Ruby 1.9
- Sử dụng ! thay cho not
# không nên dùng
x = (not something)
# nên dùng
x = !something
- Trảnh việc sử dụng !!
# không nên dùng
x = 'test'
if !!x
# body
end
# nên dùng
x = 'test'
unless x.nil?
# body
end
- Sử dụng || và && thay thế cho từ khóa or và and
# không nên
if some_condition and some_other_condition
do_something
end
# không nên
document.saved? or document.save!
# nên dùng &&
if some_condition && some_other_condition
do_something
end
# nên dùng ||
document.saved? || document.save!
- Không sử dụng ?: cho nhiều dòng, sử dụng if/else để thay thế
- Sử dụng if/unless ở cuối dòng với 1 dòng lệnh bên trong
# không nên
if some_condition
do_something
end
# nên viết trên một dòng
do_something if some_condition
# Không nên sử dụng if/unless ở cuối block
# không nên
10.times do
# multi-line body omitted
end if some_condition
# nên dùng
if some_condition
10.times do
# multi-line body omitted
end
end
- Không nên dùng if not ... hay if !...
# không nên
do_something if !some_condition
# không nên
do_something if not some_condition
# nên dùng
do_something unless some_condition
- Không nên dùng unless đi cùng với else.
# không nên
unless success?
puts 'failure'
else
puts 'success'
end
# nên dùng
if success?
puts 'success'
else
puts 'failure'
end
- Không nên dùng dấu () để bọc tất cả các điều kiện bên trong cho if/unless/while/until.
# không nên dùng ()
if (x > 10)
# body omitted
end
# nên dùng
if x > 10
# body omitted
end
- Nên dùng while/until ở cuối với một dòng lệnh
# không nên dùng while với câu lệnh đơn như thế này
while some_condition
do_something
end
# nên dùng
do_something while some_condition
- dụng until thay thế cho while với điều kiện phủ định
# không nên
do_something while !some_condition
# nên dùng until
do_something until some_condition
- dụng Kernel#loop thay thế cho while/until khi bạn cần 1 vòng lặp vô hạn
# không nên
while true
do_something
end
until false
do_something
end
# nên dùng
loop do
do_something
end
- dụng Kernel#loop với break để thay thế cho begin/end/until hoặc begin/end/while
# không nên
begin
puts val
val += 1
end while val < 0
# nên dùng
loop do
puts val
val += 1
break unless val < 0
end
- dấu ngoặc với option là một hash
# không nên
user.set({ name: 'John', age: 45, permissions: { read: true } })
# nên dùng
user.set(name: 'John', age: 45, permissions: { read: true })
- Hạn chế dùng dấu () và {} nếu có thể
class Person < ActiveRecord::Base
# không nên
validates(:name, { presence: true, length: { within: 1..10 } })
# nên dùng
validates :name, presence: true, length: { within: 1..10 }
end
- Không dùng dấu () khi gọi hàm không có đối số
# không nên
Kernel.exit!()
2.even?()
fork()
'test'.upcase()
# nên dùng
Kernel.exit!
2.even?
fork
'test'.upcase
- Không nên dùng do ... end với block chỉ có một dòng
names = ['Bozhidar', 'Steve', 'Sarah']
# không nên
names.each do |name|
puts name
end
# nên dùng
names.each { |name| puts name }
# không nên
names.select do |name|
name.start_with?('S')
end.map { |name| name.upcase }
# nên dùng
names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
- Không cần sử dụng return với trường hợp không cần thiết
# không nên
def some_method(some_arr)
return some_arr.size
end
# nên dùng
def some_method(some_arr)
some_arr.size
end
- Không sử dụng self trong trường hợp không cần thiết
# không nên dùng self nếu không set giá trị
def ready?
if self.last_reviewed_at > self.last_updated_at
self.worker.update(self.content, self.options)
self.status = :in_progress
end
self.status == :verified
end
# nên dùng
def ready?
if last_reviewed_at > last_updated_at
worker.update(content, options)
self.status = :in_progress
end
status == :verified
end
- Không sử dụng các biến địa phương và biến truyền vào cùng tên nếu như chúng không tương đương nhau
class Foo
attr_accessor :options
# có thể dùng
def initialize(options)
self.options = options
# cả options và self.options là tương đương nhau
end
# không nên
def do_something(options = {})
unless options[:when] == :later
output(self.options[:message])
end
end
# nên dùng
def do_something(params = {})
unless params[:when] == :later
output(options[:message])
end
end
end
- Không sử dụng gán biến với dấu = trong điều kiện if, trừ khi được bọc bởi dấu ngoặc ()
# không nên gán ngay trong điều kiện mà không dùng ()
if v = array.grep(/foo/)
do_something(v)
...
end
# dùng được, nhưng rubocop sẽ vẫn báo lỗi
if (v = array.grep(/foo/))
do_something(v)
...
end
# nên dùng thế này cho minh bạch
v = array.grep(/foo/)
if v
do_something(v)
...
end
- Nên dùng các toán tử ngắn hơn
# không nên
x = x + y
x = x * y
x = x**y
x = x / y
x = x || y
x = x && y
# nên rút gọn lại như sau
x += y
x *= y
x **= y
x /= y
x ||= y
x &&= y
- Nên sử dụng ||= để khởi tạo biến khi nó chưa chắc chắn là đã khởi tạo
# không nên
name = name ? name : 'Bozhidar'
# không nên
name = 'Bozhidar' unless name
# Nên dùng, nó sẽ set name là 'Bozhidar' nếu như name là nil hoặc false
name ||= 'Bozhidar'
Không nên dùng ||= để khởi tạo biến boolean
# Không nên, vì nó sẽ set enabled là true ngay cả khi enabled đang là false
enabled ||= true
# nên dùng
enabled = true if enabled.nil?
- Sử dụng &&= để xử lí các biến nếu như không chắc nó có tồn tại hay không
# không nên
if something
something = something.downcase
end
# không nên
something = something ? nil : something.downcase
# cũng được
something = something.downcase if something
# nên dùng
something = something && something.downcase
# tốt nhất
something &&= something.downcase
- Không sử dụng === một cách không rõ ràng
# không nên
Array === something
(1..100) === 7
/something/ === some_string
# nên dùng
something.is_a?(Array)
(1..100).include?(7)
some_string =~ /something/
- Không nên có dấu cách giữa hàm và đối số của nó khi gọi
# không nên
f (3 + 2) + 1
# nên
f(3 + 2) + 1
- Sử dụng → cho 1 dòng lệnh và lambda cho block nhiều dòng lệnh
# không nên
l = lambda { |a, b| a + b }
l.call(1, 2)
# correct, but looks extremely awkward
l = ->(a, b) do
tmp = a * 7
tmp * b / 50
end
# nên
l = ->(a, b) { a + b }
l.call(1, 2)
l = lambda do |a, b|
tmp = a * 7
tmp * b / 50
end
- Sử dụng sprintf thay cho String#%
# không nên
'%d %d' % [20, 10]
# => '20 10'
# nên dùng
sprintf('%d %d', 20, 10)
# => '20 10'
# nên dùng
sprintf('%{first} %{second}', first: 20, second: 10)
# => '20 10'
format('%d %d', 20, 10)
# => '20 10'
# nên dùng
format('%{first} %{second}', first: 20, second: 10)
# => '20 10'
- Sử dụng Array#join thay cho Array#*
# không nên
%w(one two three) * ', '
# => 'one, two, three'
# nên dùng
%w(one two three).join(', ')
# => 'one, two, three'
- Sử dụng các ranges hoặc Comparable#between? thay vì biểu thức logic phức tạp
# không nên
do_something if x >= 1000 && x <= 2000
# nên dùng
do_something if (1000..2000).include?(x)
# nên dùng
do_something if x.between?(1000, 2000)
- Sử dụng các phương thức đã được cung cấp sẵn thay thế cho việc so sánh ==
# không nên
if x % 2 == 0
end
if x % 2 == 1
end
if x == nil
end
# nên dùng
if x.even?
end
if x.odd?
end
if x.nil?
end
if x.zero?
end
if x == 0
end
- Không nên dùng điều kiện kiểm tra nil với phủ định
# không nên
do_something if !something.nil?
do_something if something != nil
# có thể dùng
do_something unless something.nil?
# nên dùng
do_something if something
- Sử dụng return để rút gọn code
# không nên
def compute_thing(thing)
if thing[:foo]
update_with_bar(thing)
if thing[:foo][:bar]
partial_compute(thing)
else
re_compute(thing)
end
end
end
# nên dùng
def compute_thing(thing)
return unless thing[:foo]
update_with_bar(thing[:foo])
return re_compute(thing) unless thing[:foo][:bar]
partial_compute(thing)
end
- Sử dụng next để thay thế cho khối điều kiện
# không nên
[0, 1, 2, 3].each do |item|
if item > 1
puts item
end
end
# nên dùng
[0, 1, 2, 3].each do |item|
next unless item > 1
puts item
end
Tài liệu tham khảo
https://www.relishapp.com/womply/ruby-style-guide/docs/syntax
All rights reserved