2011-12-07 40 views
12

Nếu tôi làm điều này:Tại sao đây không phải lỗi cú pháp?

(false true) 

nó không có lỗi cú pháp, như tôi mong đợi. Nhưng nếu tôi làm điều này:

(false 
true) 

mã này được thực thi và nó sẽ loại bỏ điều kiện đầu tiên và trả về kết quả của điều kiện thứ hai.

Đây có phải là lỗi hoặc tính năng không?

+8

'(sai; đúng)' –

+2

Tôi biết phải có một giải thích đơn giản. Bạn nên đăng bài này như là một câu trả lời thực sự và yêu cầu một số tín dụng cho chính mình. :-) – L2G

Trả lời

15

kết thúc dòng là không bắt buộc, vì vậy trong trường hợp này, sự trở lại đang gây ra những phân tích cú pháp để giải thích nó như sau:

(false; true) 

mà đánh giá chỉ:

(true) 

Nếu đây là những phương pháp các cuộc gọi sau đó cả hai sẽ được đánh giá, nhưng chỉ lần cuối cùng sẽ được phát ra. Ví dụ:

x = (p "hello" 
p "world" 
2) 

chí này ra "hello" và "thế giới" và x sẽ bằng 2

7

ngoặc được sử dụng cho nhóm, ngắt dòng được sử dụng như dải phân cách biểu hiện. Vì vậy, những gì bạn có ở đây chỉ đơn giản là một nhóm hai biểu thức. Không có gì để từ chối.

này rất hữu ích vì thành ngữ nổi tiếng này:

def foo(bar = (bar_set = true; :baz)) 
    if bar_set 
    # optional argument was supplied 
    end 
end 

Có chỉ đơn giản là không có cách nào khác trong Ruby để tìm hiểu xem một đối số tùy chọn được cung cấp hay không.

Về cơ bản, điều này trở nên thú vị khi có các tác dụng phụ, chẳng hạn như gán một biến trong ví dụ của tôi hoặc in ra màn hình trong ví dụ của @ 32bitkid. Trong ví dụ của bạn, không có tác dụng phụ, đó là lý do tại sao bạn không thể thấy những gì là thực sự là đang diễn ra.

+0

Trên thực tế, thành ngữ đó là mới đối với tôi, vì vậy tôi đánh giá cao câu trả lời của bạn! – L2G

+0

@ L2G: Nó không được sử dụng thường xuyên, nhưng có một số giao thức chuẩn yêu cầu phân biệt giữa việc có hay không một đối số tùy chọn được cung cấp. 'inject' là một ví dụ. Thông thường nó được thực hiện trong C hoặc Java hoặc C#, với đặc quyền truy cập vào các thông dịch viên internals, mà làm cho nó dễ dàng để kiểm tra sự tồn tại của một đối số tùy chọn. Nhưng nếu bạn muốn sao chép hành vi của nó trong Ruby thuần khiết, bạn phải sử dụng các thủ thuật như thế này. –

2

Ruby có thể cảnh báo bạn nếu bạn có cảnh báo.

$VERBOSE = true 
def foo 
    (false 
    true) 
end 

mang đến cho bạn

(irb):3: warning: unused literal ignored 

Trong cả hai của Ruby 1.9.1 patchlevel 378 và Ruby 1.8.7 patchlevel 330.

Xem How can I run all Ruby scripts with warnings? cho làm thế nào để chạy tất cả các kịch bản Ruby với cảnh báo trên.

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