2013-02-19 27 views
6

Cốt truyện dài, tôi đã viết một phương thức bao gồm một đối số tùy chọn, sẽ thực hiện một số thứ nếu giá trị cho khóa: nếu được đánh giá là đúng. Khi tôi cố gắng băm trong IRB sử dụng cú pháp mới tôi nhận được một lỗi cú pháp trong IRB, việc nghỉ nhanh chóng mở:IRB - Cú pháp băm Ruby 1.9.x: {if: true} không bằng {: if => true}

1.9.3p374 :010 > {if: true} 
1.9.3p374 :011?> 

Sử dụng cú pháp cũ, làm việc tốt:

1.9.3p374 :011 > {:if => true} 
=> {:if=>true} 

Tất cả từ khóa bắt đầu một tuyên bố, thể hiện hành vi tương tự. Ví dụ. def, do, module, case

từ dành riêng khác xảy ra ở giữa và class chỉ làm việc tốt: else, end

Câu hỏi của tôi là: Liệu hành vi này được mong đợi, một lỗi hoặc một giới hạn?

+2

'irb' hơi mỏng manh và có tổn thương não khá lớn, có thể bạn sẽ thấy một số điều đó. –

+0

@muistooshort có vẻ khá vô căn cứ. 'echo 'đặt {if: true} .inspect'> test.rb; ruby test.rb' trả về: 'test.rb: 1: lỗi cú pháp, bất ngờ ':'' Trong thời trang nào là 'irb' mong manh? – nzifnab

+2

@nzifnab Irb phải dừng thực hiện câu lệnh cho đến khi 'kết thúc', và nếu nó diễn giải sai một toán tử điều khiển (như ở đây) thì có thêm các vấn đề khác. – coreyward

Trả lời

6

Thật khó để phân tích cú pháp một cách đáng tin cậy và rõ ràng bằng mọi ngôn ngữ. Điều này đặc biệt đúng khi bạn bắt đầu sử dụng các từ dành riêng. Và irb phải vượt xa điều đó và cung cấp một mô hình tương tác trên đầu trang của trình phân tích cú pháp, điều này thậm chí còn khó hơn. Cá nhân tôi không nghĩ rằng có quá nhiều giá trị đáng lo ngại về các trường hợp như thế này, hoặc là người dùng ngôn ngữ hoặc là người bảo trì. Trong tâm trí của tôi, nó là tốt hơn để chỉ đơn giản là tìm ra những gì làm việc và tránh nhận được vào những tình huống này nếu có thể.

Bạn có thể thấy một số hành vi tương tự trong Ruby thuần túy, bên ngoài irb. Ví dụ:

puts({if: true}) # no problem, behaves as expected in Ruby 1.9.3. 
puts {if: true} # raises a syntax error in Ruby 1.9.3 

Để trả lời câu hỏi của bạn, nó là "hành vi mong đợi, một lỗi hoặc một giới hạn", tôi muốn nói rằng bạn nên bỏ qua irb và so sánh nó với đồng bằng Ruby, và nếu bạn làm điều này, nó hoạt động tốt. Điều đó có nghĩa nó phải là một lỗi irb.

Nhưng liệu có thể hoặc đáng giá để giải quyết? @coreyward làm cho một điểm tốt trong bình luận của mình rằng irb phải trì hoãn thực hiện trong hầu hết trường hợp khi nó gặp một if. Bạn sẽ phải nhìn xa hơn để biết chắc chắn, nhưng bạn có thể không giải thích rõ ràng tất cả các trường hợp như thế này.

Lời khuyên của tôi: tránh toàn bộ cấu trúc này nếu bạn có thể và không sử dụng các từ dành riêng cho nhãn nếu bạn có thể tránh được!

Đây là tệp bạn có thể chạy với Ruby đơn giản (ví dụ MRI). Bạn sẽ thấy {:if=>true} ở đầu ra để xác nhận nó hoạt động.

{if: true} 
foo = {if: true} 
# if MRI is working, should be able to execute this file without trouble. 
p foo 
+1

Nó cũng đáng chú ý là nếu bạn giới thiệu bài tập mọi thứ hoạt động như mong đợi. Ví dụ.'foo = {if: true}' đánh giá tốt trong MRI (mặc dù IRB vẫn đi lên). – coreyward

+0

@coreyward: thực sự. Tôi đã thử điều này. Tôi sẽ thêm một khối mã vào câu trả lời của tôi để làm rõ. cảm ơn! – Peter

+1

Tất cả đều rất thú vị. Ví dụ của OP không thành công trong kịch bản lệnh ruby ​​hay trong IRB, nhưng khi bạn ném dấu ngoặc đơn xung quanh dấu ngoặc đơn nó hoạt động. Làm thế nào khó hiểu! Tôi gần như muốn họ bị mắc kẹt với hash-rocket độc quyền. Vì vậy, dễ dàng hơn nhiều để hiểu và gotchas ít hơn nhiều (và sau đó tất cả các hash là như nhau thay vì 'băm với các phím chuỗi sử dụng tên lửa! Băm với nhãn dành riêng sử dụng tên lửa! Ký hiệu đôi khi nên sử dụng cú pháp nhãn!) Ugh. – nzifnab

Các vấn đề liên quan