5 tips trong Ruby có thể bạn chưa biết

Trong bài viết này chúng ta sẽ khám phá các chủ đề sau:

  • Gán phần còn lại của một mảng cho một biến
  • Hủy cấu trúc của mảng trong block đối số
  • Hash#default_proc làm giá trị mặc định
  • HEREDOC và kết hợp phương thức
  • Toán tử đơn phân cho các tượng không phải số

Gán phần còn lại của một mảng cho một biến

Khi hủy cấu trúc của một mảng, bạn có thể bung và gán phần còn lại của nó cho một biến bằng cách sau

a = [1, 2, 3]
b, *rest = *a

b    # => 1
rest # => [2, 3]
a    # => [1, 2, 3]

Hủy cấu trúc của mảng trong block đối số

Nó khả thi khi sử dụng cơ chế Array Destructuring trong ruby blocks

array = [
  [:key1, :value1],
  [:key2, :value2],
  [:key3, :value3],
  [:key4, :value4]
]

array.each do |key, value|
  puts "#{key}: #{value}"
end

Kết quả

key1: value1
key2: value2
key3: value3
key4: value4

Ở đây, mỗi sub-array bị hủy cấu trúc và các giá trị đầu tiên và thứ hai của nó được gán cho các đối số tương ứng là keyvalue

Hash#default_proc làm giá trị mặc định

Hash.new có thể dùng một block để thiết lập giá trị mặc định của một key

h = Hash.new { |h, k| h[k] = {} }

h[:layer_1]           # => {}
h[:layer_1][:layer_2] # => nil

Nhưng nếu chúng ta muốn tất cả giá trị mặc định này được truyền qua tất cả các mục và mục con của một hash ?

Nó khả thi khi khối mặc định được chuyển làm đối số của phương thức Hash.new cho tất cả các mục con.

Để làm điều đó chúng ta có thể sử dụng phương thức Hash#default_proc có chứa khối được truyền làm đối số của phương thức Hash.new

layers = Hash.new do |layers, layer_name|
  layers[layer_name] = Hash.new(&layers.default_proc)
end

layers[:layer_1][:layer_2][:layer_3] = 'a secret'

layers # => { layer_1: { layer_2: { layers_3: 'a secret' } } }

Ở đây, một hash mới nhận một khối làm đối số -- được sử dụng để thiết lập giá trị mặc định của một mục mới -- được gán cho biến layers

Khi layers[:layer_1] được gọi mà không có một phép gán rõ ràng thì khối được truyền vào dưới dạng đối số của hash layers được thực hiện

Khối này được thực hiện như sau

layers[layer_1] = Hash.new(&layers.default_proc)

# SAME AS

layers[:layer_1] = Hash.new do |layers, layer_name|
  layers[layer_name] = Hash.new(&layers.default_proc)
end

Trong thực tế, hàm default_proc thực thi khối được truyền dưới dạng tham số của hash layers

Điều nảy tương tự với layers[:layer_1][:layer_2]

Và sau đó layers[:layer_1][:layer_2][:layer_3] chứa một giá trị được gán. Vì vậy phương thức default_proc không được gọi

Phương thức default_proc của hash layers được truyền như giá trị mặc định cho bất kỳ mục mới và mục con của hash này

HEREDOC và kết hợp phương thức

HEREDOC là một cú pháp chuỗi nhiều dòng, sau đó nó có thể kết hợp với các phương thức trên đó.

sql = <<-SQL.gsub("\n", ' ').squish
SELECT MIN(u.popularity)
FROM users u
WHERE
  u.created_at <= #{Time.now} AND u.created_at >= #{Time.now - 7.days}
SQL

puts sql

Kết quả

SELECT MIN(u.popularity) FROM users u WHERE u.created_at <= 2018-04-23 21:42:00 +0200 AND u.created_at >= 2018-04-16 21:42:00 +0200

Note: phương thức squish chỉ có ở trong Rails

Toán tử đơn phân cho các tượng không phải số

Có thể triển khai toán tử đơn phân cho các đối tượng bằng cách khai báo các phương thức [email protected][email protected] trong class

class True
  def -@
    false
  end
  
  def +@
    true
   end
end

t = True.new

p -t
p +t

Kết quả

false
true

Cảm ơn các bạn bạn đã đọc bài viết của mình ^^

Link nguồn của tác giả Mehdi Farsi: https://medium.com/@farsi_mehdi/5-ruby-tips-you-probably-dont-know-76fee34cfd0c