Posts Các loại arguments trong ruby
Post
Cancel

Các loại arguments trong ruby

Các method trong Ruby có thể nhận 0 hoặc nhiều arguments. Những arguments này được triển khai theo nhiều cách khác nhau và có thứ tự ưu tiên của riêng nó.

Các loại arguments

Required argument

Khi gọi method, bạn phải cung cấp đủ số lượng argument tới method, nếu không Ruby sẽ raise exception.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Class Person
  def call(name)
	puts "Hello, #{name}"
  end
end

Person.new.call("Phuc dep trai")
# "Hello, Phuc dep trai"

Person.new.call
# ArgumentError (wrong number of arguments (given 0, expected 1))

Person.new.call("Phuc dep trai", "18 tuoi")
# ArgumentError (wrong number of arguments (given 2, expected 1))

Optional argument / Sponge argument / Non-required argument

Bạn vẫn có thể define method với số lượng argument tùy ý bằng cách đặt dấu sao (*) (splat operator) trước argument. Dấu * nghĩa là bạn có thể truyền vào số lượng argument bất kỳ hoặc không cần truyền và (*args) được xem như là 1 array các arguments

1
2
3
4
5
6
7
8
9
10
class Person
  def call(*opt_args)
	p opt_args
  end
end

Person.new.call("Phuc dep trai", "18 tuoi")
# => ["Phuc dep trai", "18 tuoi"]

Person.new.call # => []

Chúng ta có thể kết hợp required argument với optional argument để tinh chỉnh số lượng argument tùy ý.

1
2
3
4
5
6
7
8
9
def call(name, age, *hobbies)
  p name, age, hobbies
end

Person.new.call("Phuc dep trai", 18, "read book", "game")
# "Phuc dep trai"
# 18
# ["read book", "game"]
# => ["Phuc dep trai", 18, ["read book", "game"]]

Ngoài single splat operator (*), chúng ta có double splat operator (**). Cách hoạt động tương tự như single splat operator, là một optional argument và (**args) được xem như là 1 hash các arguments.

1
2
3
4
5
6
7
8
9
def call(a, b, **opts)
  p a, b, opts
end

call(1, 2, x: 10, y: 100)
# 1
# 2
# {:x=>10, :y=>100}
# => [1, 2, {:x=>10, :y=>100}]

Default-valued argument

Có thể nói argument với default value cũng là 1 dạng optional argument và c = 1 dưới đây là default-valued argument.

1
2
3
4
5
6
def default_arg(a, b, c=1)
  p a,b,c
end

default_arg(1, 2) # => 1, 2, 1
default_arg(1, 2, 3) # => 1, 2, 3

Keyword (named) argument

Loại này khá giống với việc truyền hash vào argument nhưng bắt buộc phải truyền vào khi nó được khai báo mà không có default value. Nếu argument được truyền vào mà thiếu thì ruby sẽ raise exception.

1
2
3
4
5
6
7
8
9
10
11
12
13
def kw_arg(a:, b:)
  p a, b
end

kw_arg(a: 1, b: 2) # => [1, 2]
kw_arg # => ArgumentError (missing keyword: :a, :b)

def kw_arg(a: 1, b: 2)
  p a, b
end

kw_arg # => [1, 2]
kw_arg(a: 10) # => [10, 2]

Thứ tự ưu tiên

Dưới đây là thứ tự của argument nếu bạn muốn kết hợp các loại arguments và có thể tránh lỗi cú pháp.

required -> default-valued -> optional -> keyword

Ví dụ tổng hợp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Required argument: a
# Default-valued argument: b
# Optional arguments: c, f
# Keyword arguments: d, e

def  m(a, b = 100, *c, d: 1, e:, **f )
  p a, b, c, d, e, f
end

m(1, 2, 3, 4, d: 5, e: 6, x: 100, y: 200)
# => [1, 2, [3, 4], 5, 6, {:x=>100, :y=>200}]

m(1, 2, d: 5, e: 6, x: 100, y: 200)
# => [1, 2, [], 5, 6, {:x=>100, :y=>200}]

m(1, d: 5, e: 6, x: 100, y: 200)
# => [1, 100, [], 5, 6, {:x=>100, :y=>200}]

m(1, e: 6, x: 100, y: 200)
# => [1, 100, [], 1, 6, {:x=>100, :y=>200}]

m(1, e: 6)
# => [1, 100, [], 1, 6, {}]

Dưới đây là 1 số ví dụ về các loại arguments cũng như thứ tự triển khai của nó. sample-ruby-arguments

Lưu ý

  • Không đặt default-valued argument bên phải của optional argument
1
2
def broken_args(x,*y,z = 100); end
# => syntax error, unexpected '=', expecting ')'

Nếu bạn chạy dòng code này thì sẽ thấy báo lỗi syntax hoặc code không hoạt động là vì sai syntax. Giả dụ đoạn code này đúng và bạn test nó: broken_args(1, 2, 3, 4). Bản chất của splat operator *ylấy tất cả các arguments còn lại. Do đó, Ruby sẽ không biết là y = 2, 3, 4 và z = 100 hay là y = 2, 3 và z = 4

Tài liệu tham khảo

  • The Well grounded Rubyist - David A.Black - chapter 2.4
This post is licensed under CC BY 4.0 by the author.