2009-12-27 20 views
33

Để viết ngắn gọn hơn, chứ không phải làm điều này:Được gán trong một điều khoản ruby ​​có điều kiện tốt?

test_value = method_call_that_might_return_nil() 
if test_value 
    do_something_with test_value 
end 

Tôi đã gán trong điều kiện:

if test_value = method_call_that_might_return_nil() 
    do_something_with test_value 
end 

là phong cách xấu này? Cú pháp vẫn còn hơn-ngắn gọn:

do_something_with test_value if test_value = method_call_that_might_return_nil() 

không được theo Matz (http://redmine.ruby-lang.org/issues/show/1141) cho phép, như đã thảo luận in another SO question, và sẽ vẫn như vậy trong 1,9,.

Do sự nhầm lẫn có thể có của việc chuyển nhượng và so sánh, điều này có khiến việc đọc mã không quá khó khăn?

+0

Tôi nghĩ rằng một dòng phải được rút ra giữa sự đồng nhất và dễ hiểu. Tôi nghĩ trong thời đại ngày nay, nơi chúng ta phải biết một số ngôn ngữ khác nhau, một ý tưởng hay là sử dụng các tính năng mới tuyệt vời của một số ngôn ngữ mà không làm hư hại kiến ​​thức lập trình viên bất động sản hiện có. Là một lập trình viên chuyên gia, tại sao tôi nên có sự cần thiết phải google phù hợp cú pháp như vậy từ ngôn ngữ này sang ngôn ngữ khác? Tôi sẽ dành nhiều thời gian để giải quyết vấn đề trong tầm tay. Ví dụ, làm thế nào để đa luồng trong ruby. –

+1

Rubocop và hướng dẫn kiểu ruby ​​này khuyên bạn nên tránh: https://github.com/bbatsov/ruby-style-guide – Rimian

+0

Liên kết tới phần cụ thể của hướng dẫn kiểu: https://github.com/bbatsov/ruby-style -guide # safe-assignment-in-condition –

Trả lời

14

Câu hỏi này được hỏi QUITE một lúc trước và tất cả các câu trả lời đều lỗi thời.

Đó là phong cách GOOD rõ ràng để sử dụng các bài tập trong điều kiện. Nếu bạn làm như vậy, hãy quấn điều kiện trong dấu ngoặc đơn.

# Bad 

if value = Settings.get('test_setting') 
    perform_action(value) 
end 

# Okay, but uncommon and verbose 

value = Settings.get('test_setting') 
if value 
    perform_action(value) 
end 

# Good 

if (value = Settings.get('test_setting')) 
    perform_action(value) 
end 

See the community style guide for more information

Câu trả lời được chấp nhận trước đây cho biết sử dụng từ khoá and. Không bao giờ sử dụng các từ khóa and hoặc or bằng ruby. Đó cũng là trong hướng dẫn phong cách, và có những lý do hợp lý rất tốt để không sử dụng chúng.

1

Vâng, tôi cho rằng đó là kiểu xấu do có thể nhầm lẫn giữa chuyển nhượng và so sánh. Nó chỉ còn một dòng để gán và sau đó kiểm tra, và tránh việc ai đó trong tương lai nghĩ rằng đó là lỗi và vá nó để sử dụng == thay thế.

26

Một hơi thành ngữ phổ biến là sử dụng and, trong đó sẽ giống như thế này:

tmp = method_call_that_might_return_nil and do_something_with tmp 

Một khả năng khác sẽ được gọi #nil? một cách rõ ràng, như vậy mục đích trở thành một chút rõ ràng hơn; đặc biệt là nó thực sự rõ ràng rằng bạn thực sự nghĩa gán thay vì so sánh:

unless (tmp = method_call_that_might_return_nil).nil? 
    do_something_with tmp 
end 
7

mã ngắn gọn là mã không nhất thiết phải tốt hơn. Concision rất hữu ích khi nó cải thiện giao tiếp của hành vi mã dự định từ tác giả đến các nhà duy trì trong tương lai. Tôi nghĩ rằng đủ chúng ta đến từ nguồn gốc, trong đó chúng ta đã có các bài tập ngẫu nhiên trong các khối if (khi chúng ta có sự so sánh bình đẳng) mà chúng ta thích phong cách hơn. Các thành ngữ .nil? đã được đề cập có tài sản đó, và tôi muốn xem xét nó sạch hơn là có sự phân công trần bên trong điều kiện if. Thực sự, mặc dù, tôi không thấy những tổn hại trong việc có thêm dòng mã cho nhiệm vụ.

2

Các lập trình viên C thực hiện việc này rất nhiều. Tôi không thấy một vấn đề với nó trong Ruby, miễn là nó rõ ràng những gì đang xảy ra.

+3

Vấn đề là ruby ​​đưa ra cảnh báo bất cứ khi nào bạn chỉ định trong điều kiện. Nếu không, tôi nghi ngờ nó sẽ phổ biến trong ruby ​​như trong C. –

1

Tôi nghĩ nó ổn. Sự ác cảm đối với sự phân công trong một điều kiện xuất phát từ việc biết rằng một đột quỵ quan trọng bị nhỡ khi gõ == chuyển một phép so sánh thành một nhiệm vụ không mong muốn. Nghiêm cấm việc sử dụng bài tập trong tình trạng khiến các tai nạn như vậy xuất hiện như mắt (và đôi khi đối với ngôn ngữ, như trong C, nơi có thể tạo ra nhiều trình biên dịch để phát ra cảnh báo nếu họ gặp phải một bài tập trong điều kiện). Mặt khác, các xét nghiệm cũng làm cho tai nạn như vậy nổi bật. Nếu mã của bạn được kiểm tra đầy đủ, bạn có thể xem xét loại bỏ các lệnh cấm đó.

5

Cách lập trình chức năng để thực hiện việc này là sử dụng andand. Đó là một cách có thể đọc được chuỗi các cuộc gọi phương thức để một số không ở giữa dừng chuỗi. Vì vậy, ví dụ của bạn sẽ giống như sau:

method_call_that_might_return_nil.andand.tap {|obj| do_something_with obj} 
## or, in the common case: ## 
method_call_that_might_return_nil.andand.do_something 
Các vấn đề liên quan