Có ba cách sử dụng chung. Một cách là sử dụng các giá trị mặc định để thiết lập một biến khác cho thấy có hay không giá trị mặc định được đánh giá:
def f(p1 = (no_argument_passed = true; nil))
'no arguments passed' if no_argument_passed
end
f # => 'no arguments passed'
f(nil) # => nil
Cách thứ hai là sử dụng một số đối tượng mà chỉ được biết đến trong các phương pháp như giá trị mặc định, do đó người ngoài là không thể chuyển đối tượng đó vào:
-> {
undefined = BasicObject.new
define_method(:f) do |p1 = undefined|
'no arguments passed' if undefined.equal?(p1)
end
}.()
f # => 'no arguments passed'
f(nil) # => nil
Trong số hai thứ này, cái đầu tiên là thành ngữ hơn. Cái thứ hai (thực sự, một biến thể của nó) được sử dụng bên trong Rubinius, nhưng tôi chưa bao giờ gặp nó ở bất cứ nơi nào khác.
Một giải pháp thứ ba sẽ được thực hiện một số biến của tham số sử dụng biểu tượng báo:
def f(*ps)
num_args = ps.size
raise ArgumentError, "wrong number of arguments (#{num_args} for 0..1)" if num_args > 1
'no arguments passed' if num_args.zero?
end
f # => 'no arguments passed'
f(nil) # => nil
Lưu ý rằng điều này đòi hỏi bạn phải tái thực hiện arity Ruby kiểm tra bằng tay. (Và chúng tôi vẫn chưa hiểu đúng, vì điều này làm tăng ngoại lệ bên trong phương pháp, trong khi Ruby sẽ tăng nó tại trang web gọi.) Nó cũng yêu cầu bạn ghi lại chữ ký phương thức của mình theo cách thủ công vì trình tạo tài liệu tự động như vậy vì RDOC hoặc YARD sẽ phỏng đoán một số tham số tùy ý thay vì một tham số tùy chọn.
Nguồn
2014-05-20 18:40:54
Nếu p1 được mặc định là không, không chuyển số không giống như không? – Cereal
@Cereal Vui lòng xem câu hỏi, tôi đã thêm một trường hợp sử dụng. Vì vậy, nếu tôi không thể phân biệt giữa không có giá trị và 'nil', tôi không thể đặt giá trị của biến thành' nil'. Người ta có thể lập luận rằng tôi nên chọn giá trị mặc định khác nhau, nhưng tôi tin rằng 'nil' là giá trị thích hợp nhất trong trường hợp này. Ngoài ra, nó có thể là bạn không thể mong đợi biến để không mất một số giá trị. –