2013-04-03 26 views
9

Việc đặt giá trị mặc định cho một cuộc tranh luận splat đưa ra một lỗi:Làm thế nào để đặt một giá trị mặc định cho một cuộc tranh luận splat trong Ruby

1.9.3-p374 :001 > def a b, *c = nil 
1.9.3-p374 :002?> end 
SyntaxError: (irb):1: syntax error, unexpected '=', expecting ';' or '\n' 
def a b, *c = nil 
      ^
    from /Users/me/.rvm/rubies/ruby-1.9.3-p374/bin/irb:16:in `<main>' 

Một số biến thể tôi đã cố gắng mà không làm việc, hoặc:

1.9.3-p374 :003 > def a b, *c = [] 
1.9.3-p374 :005 > def a b, (*c) = nil 
1.9.3-p374 :007 > def a b, (*c = []) 
1.9.3-p374 :009 > def a b, (*c = [1,2,3]) 
1.9.3-p374 :011 > def a b, *c = [1,2,3] 

Tôi không thấy một vấn đề không xác định ở đây, do đó, có vẻ như nó sẽ là có thể.

liên quan: Why non-explicit splat param plus default param is wrong syntax for method definition in Ruby 1.9?

+1

Splat luận theo mặc định là rỗng mảng – fl00r

+1

Có, nhưng những gì về một đối số mặc định? – jordanpg

+0

Có lý do nào bạn chưa chấp nhận câu trả lời chưa? – vlasits

Trả lời

6

Cách sử dụng đã cố gắng của bạn là chống lại các quy ước xung quanh việc sử dụng thẻ nhớ. Splats được cho là (ít nhất là trong Ruby) để chiếm tất cả các giá trị thêm (0, 1 hoặc nhiều hơn).

Nếu bạn biết rằng bạn muốn giá trị thứ hai trong đối số phương pháp của bạn danh sách để có một giá trị mặc định, bạn có thể mang nó ra khỏi splat và liệt kê nó ngay trước khi splat với một giá trị mặc định như thế này:

def a b, c=nil, *d 
    # rest of code omitted 
end 

CHỈNH SỬA: Để trả lời câu hỏi của bạn tại sao nó không hoạt động hoàn toàn rõ ràng. Đó là một quyết định thiết kế của nhà thiết kế ngôn ngữ. Matz không bao giờ dự định toán tử splat làm việc với các giá trị mặc định. Điều này có vẻ khá hợp lý đối với tôi vì nó được sử dụng để đánh bắt một số biến không xác định và bởi vì phương pháp tôi mô tả đọc rõ ràng hơn khả năng bạn mô tả và bởi vì tất cả các vấn đề mà các ví dụ của bạn giải quyết đều có thể giải quyết được theo những cách khác.

+1

+1 Đây là cách phù hợp để thực hiện việc này. Nếu 'c' là đặc biệt, hãy đẩy nó vào mục nhập tham số riêng của nó và không chơi trò chơi cố gắng trích xuất nó từ biến được chia nhỏ. –

0

Biểu tượng mặc định tham số để một mảng trống rỗng, mà không cần phải của bạn để làm bất cứ điều gì đặc biệt.

def a(b, *c) 
    c 
end 

a("foo") 
#=> [] 
+0

Có, nhưng còn đối số mặc định ngoài nil thì sao? – jordanpg

+0

Xem câu trả lời của tôi cho những việc cần làm khi bạn muốn c có giá trị mặc định – vlasits

2

Bạn có thể đặt giá trị mặc định trong chính phương thức khi biết rằng biểu tượng mặc định trả về một mảng trống.

def test(a, *b) 
    b = "default b" if b == [] # edited as per Tin Man's recommendation 
    puts [a, b].inspect 
end 

test("Test", 1, 2) 
# => ["Test", [1, 2]] 
test("Test") 
# => ["Test", "default b"] 

Trong Rails, bạn có thể kiểm tra b.present? dưới dạng một mảng trống được coi là trống. Hy vọng rằng sẽ giúp.

+0

'b == [] và b =" mặc định b "' không được khuyến nghị cho kiểu Ruby. Sử dụng 'b =" mặc định b "nếu b == []'. –

+0

Cảm ơn, tôi đã kết hợp đề xuất của bạn. Có lý do kỹ thuật nào đằng sau điều này không? –

+4

Đó là vấn đề về khả năng đọc và bảo trì. Sử dụng một boolean để tham gia kiểm tra có điều kiện và gán là rất nhiều cấu trúc C/Perl; Đó là terse, gần như khó hiểu, mà không đạt được sự đáng tin cậy, nếu có, tốc độ. Khi viết trong C hoặc Perl, người ta mong đợi, gần như là macho, để có thể viết như thế, nhưng cách Ruby là để cho một chút về sự dễ chịu cho dễ đọc hơn.Ngoài ra, nếu bạn sử dụng 'và', và sau đó thêm các bài kiểm tra bổ sung hoặc bài tập, thứ tự ưu tiên có thể cắn bạn, có thể rất khó để theo dõi. Sử dụng '&&' tránh được vấn đề ưu tiên nhiều lần, nhưng không tăng khả năng đọc. –

0

này rất thuận lợi:

def initialize(*response_names) 
    @response_names = response_names.presence || %w(default values) 
end 
Các vấn đề liên quan