Code theo phong cách Ruby (1)

| code style tips

Bài viết này liệt kê những cách viết code theo phong cách Ruby, ngắn gọn và dễ nhìn hơn.

Đặt if ở phía sau để rút gọn

if user.active?
  send_mail_to(user)
end
send_mail_to(user) if user.active?

Dùng unless thay cho if + not

user.destroy if !user.active?
user.destroy unless user.active?

Tuy nhiên, nếu điều kiện phía sau unless phức tạp, có and, or, thì nên dùng if cho dễ hiểu.

user.destroy unless (user.active? || user.admin?) && !user.spam?

Sử dụng cách viết điều kiện thu gọn

if user.admin?
  "I appreciate for that."
else
  "Thanks."
end
user.admin? ? "I appreciate for that." : "Thanks"

Tuy nhiên, chỉ nên dùng cho những đoạn code có điều kiện đơn giản, không nên dùng với những đoạn code lồng nhau.

# khó đọc
user.admin? ? user.active? ? "I appreciate for that." : "Are you OK?" : "Thanks."

Dùng if đồng thời với phép gán

user = find_user
if user
  send_mail_to(user)
end
if user = find_user
  send_mail_to(user)
end

Tuy nhiên, cách viết này có thể gây hiểu nhầm cho người đọc: “lỗi type gõ thiếu dấu =, đáng ra phải là == hoặc != chứ”. Vì thế có người thích mà cũng có người không thích cách viết này.

Xác nhận điều kiện từ các class con

if parent.children
  if parent.children.singleton?
    singleton = parent.children.first
    send_mail_to(singleton)
  end
end

Viết gọn lại

if parent.children && parent.children.singleton?
  singleton = parent.children.first
  send_mail_to(singleton)
end

Không dùng return ở cuối method

Các ngôn ngữ khác phải cần, nhưng với ruby, cách viết không có return có vẻ được yêu thích hơn.

def build_message(user)
  message = 'hello'
  message += '!!' if user.admin?
  return message
end
def build_message(user)
  message = 'hello'
  message += '!!' if user.admin?
  message
end

Sử dụng Object#tap

def build_user
  user = User.new
  user.email = "hoge@hoge.com"
  user.name = "Taro Yamada"
  user
end
def build_user
  User.new.tap do |user|
    user.email = "hoge@hoge.com"
    user.name = "Taro Yamada"
  end
end

Khi ghép các chuỗi kí tự, không dùng “+” mà dùng “#{ }”

"Hello, " + user.name + "!"
"Hello, #{user.name}!"

Freeze các hằng số

freeze là cách khai báo một hằng số. Dùng cách này để tránh trường hợp hằng số bị thay đổi trong quá trình làm việc.

Chuỗi kí tự

CONTACT_PHONE_NUMBER = "03-1234-5678"
CONTACT_PHONE_NUMBER << "@#$%^"
puts CONTACT_PHONE_NUMBER # => 03-1234-5678@#$%^
CONTACT_PHONE_NUMBER = "03-1234-5678".freeze
CONTACT_PHONE_NUMBER << "@#$%^" # => RuntimeError: can't modify frozen String

Array

ADMIN_NAMES = ["Tom", "Alice"]
ADMIN_NAMES << "Taro"
puts ADMIN_NAMES # => ["Tom", "Alice", "Taro"]
ADMIN_NAMES = ["Tom", "Alice"].freeze
ADMIN_NAMES << "Taro" # => RuntimeError: can't modify frozen Array

Khi tạo 1 array, dùng %w( )、%i( ) thay cho []

Trường hợp muốn tạo 1 array các chuỗi kí tự, dùng %w( ) sẽ dễ viết và ngắn hơn.

actions = ['index', 'new', 'create']
actions = %w(index new create) # => ['index', 'new', 'create']

Từ Ruby 2.0 trở đi, có cách viết %i( ) để tạo symbol.

actions = %i(index new create) # => [:index, :new, :create]

Khi xử lý 1 array theo thứ tự, dùng “&:method” thay cho “object.method”

names = users.map{|user| user.name }
names = users.map(&:name)

Không chỉ có map mà cả each ,select hay các block khác đều có thể dùng cách viết này.

Comments