+1

Splat Opera trong Ruby

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 Splatparameters 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 splatparameters ở 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 splatsecond

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

Viblo
Let's register a Viblo Account to get more interesting posts.