Splat Opera trong Ruby
Bài đăng này đã không được cập nhật trong 8 năm
Như tiêu đề hôm nay mình xin giớ thiệu với các bạn cách sử dụng splat trong ruby
Method Definitions
Đầu tiên ta cùng xem ví dụ sau:
def shout_out(message, *friends)
friends.each { |f| puts "#{f}: #{message}" }
end
shout_out("Hi there!", "Bob", "Steve", "Dave")
# => "
#Bob: Hi there!
#Steve: Hi there!
#Dave: Hi there!"
Trên đây có lẽ là cách dùng Splat
phổ biến nhất. Trong trường hợp này Splat
là parameters
cuối cùng của function shout_out
. Function trên sẽ gán mesage
với giá trị là Hi there!
. và gán friends
với tất cả các biến truyền vào còn lại.
Với trường hợp splat
là parameters
ở giữa:
def shout_out(message, *friends, signoff)
friends.each { |f| puts "#{f}: #{message}" }
puts signoff
end
shout_out("Hi there!", "Bob", "Steve", "Dave", "Pete", "I'll see you later")
#=> "
#Bob: Hi there!
#Steve: Hi there!
#Dave: Hi there!
#Pete: Hi there!
I'll see you later"
=> giá trị sẽ được nhận vào như sau:
message: "Hi there!"
friends: "Bob", "Steve", "Dave", "Pete"
signoff: "I'll see you later")
Như vậy ruby xử lý rất tốt việc assign các value cho function khi được gọi. 2 ví dụ trên đều chỉ có 1 parametter sử dụng toán tử splat
. Vậy điều gì xảy ra nếu có nhiều hơn vậy?. Ta cùng tiếp tục xem ví dụ sau:
def shout_out(*messages, *friends)
friends.each do |f|
messages.each { |m| puts "#{f}: #{m}" }
end
end
shout_out("Hello!", "How are you?", "Bob", "Steve"
# =>
# Splat.rb:14: syntax error, unexpected tSTAR
#def shout_out(*mesages, *friends)
# ^
#Splat.rb:18: syntax eror, unexpected keyword_end, expecting $end
Lỗi nhăn răng . Vậy ta không thể dùng 2 splat
khi định nghĩa method được.
Multiple Variable Assignment
Ruby cũng cho phép ta gán nhiều giá trị cho nhiều biến cùng lúc mà không cần dùng splat
x, y = 10, 20
x, y = y, x
puts "#{x}, #{y}"
# 20, 10
Ví dụ trên tương đối đơn giản. ta cùng xem tiếp:
letters = ["a", "b", "c", "d", "e"]
first, second = letters
puts "#{first}, #{second}"
# a, b
Quá tuyệt vời phải không nào . Bây giờ thử dùng splat
gán giá trị coi sao
letters = ["a", "b", "c", "d", "e"]
first, *second = letters
puts "#{first}, #{second}"
# a, ["b", "c", "d", "e"]
Wow. Vậy là nó ưu tiên thằng first
trước. Rồi còn bao nhiêu gán hết cho thằng dùng splat
là second
Flatten Arrays
some_numbers = [1, 2, 3]
up_to_five = [some_numbers, 4, 5]
p up_to_five.flatten
# [1, 2, 3, 4, 5]
Giờ sử dụng `splat` thì sao?
```ruby
some_numbers = [1, 2, 3]
up_to_five = [*some_numbers, 4, 5]
p up_to_five
# [1, 2, 3, 4, 5]
Như vậy là flatten với quy mô lớn hơn được rồi =))
Array Coercion
Trong 1 số trường hợp hữu ích ta có thể sử dụng splat để tạo ra 1 array:
up_to_ten = *1..10
p up_to_ten
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Nó tương tự với (1..10).to_a
. Vậy khi khởi tạo với 1 string thì sao:
hello = *"Hello"
p hello
# ["Hello"]
Ợ. Cũng tạo được luôn. Nó làm được điều này không có nghĩa là chúng ta nên sử dụng chúng . Đơn giản là sau 1 khoảng thời gian, một ngày đẹp trời cần phải chỉnh sửa lại, khi mình đọc lại nó trong muôn vàn logic sẽ có thể chẳng hiểu gì hết. Code rất tối nghĩa
Conclusion
Tóm lại splat
là tương đối hữu ích. Nhưng chúng ta cần phải cẩn trọng khi sử dụng nó. Cần cân nhắc thật kỹ lưỡng xem nó có thực sự cần dùng hay không. Không nên vì tiết kiệm vài ký tự mà dùng chúng. Nó sẽ làm cho code của ta phức tạp hơn, hãy cố gắng xử lý vấn đề bằng điều đơn giản nhất có thể. HAPPY CODING
All rights reserved