Có phải vì các do
của cú pháp while
chỉ là đường syntaxic và như không có gì để làm với do
của một khối?
Ít hoặc nhiều, có. Đó không phải là cú pháp, nó chỉ đơn giản là một cấu trúc ngôn ngữ dựng sẵn, như def
hoặc class
, như @meagar đã viết.
Không có gì liên quan đến do
của một khối, ngoại trừ từ khóa đó là tốn kém và vì vậy việc sử dụng lại từ khóa có ý nghĩa. (Theo "đắt" Tôi có nghĩa là họ hạn chế các lập trình viên trong biểu cảm của mình.)
Trong một vòng lặp while
, có hai cách để tách các khối từ các điều kiện:
- các
do
từ khóa và
- dấu tách biểu thức.
Có, đến lượt nó, hai dải phân cách khác nhau biểu hiện trong Ruby:
- dấu chấm phẩy
;
và
- một dòng mới
Vì vậy, cả ba điều nào sau đây là hợp lệ:
while i = a.shift do puts i end # do
while i = a.shift; puts i end # semicolon
while i = a.shift
puts i end # newline
[Obvi ously, người cuối cùng sẽ không được viết theo cách đó, bạn sẽ đặt end
trên một dòng mới, được khấu trừ để khớp với while
. Tôi chỉ muốn chứng minh mức tối thiểu cần thiết để tách các bộ phận của vòng while
là gì.]
Nhân tiện: nó rất không thành ngữ để đặt điều kiện trong dấu ngoặc đơn. Ngoài ra còn có rất nhiều dấu chấm phẩy thừa trong mã của bạn. Và tên biến số i
thường được dành riêng cho một chỉ mục, không phải là một phần tử. (Tôi thường sử dụng el
cho các yếu tố chung, nhưng tôi thích nhiều tên ngữ nghĩa hơn.)
Nó cũng rất không thành ngữ để lặp lại một bộ sưu tập theo cách thủ công.Mã của bạn sẽ được nhiều hơn bằng văn bản như
a.each(&method(:puts)).clear
Không chỉ là nó dễ dàng hơn để hiểu những gì điều này (in tất cả các yếu tố của mảng và xóa tất cả các mục từ nó), nó cũng là dễ dàng hơn nhiều để viết (có không có cách nào để có được điều kiện chấm dứt sai, hoặc vít lên bất kỳ bài tập nào). Điều này cũng sẽ hiệu quả hơn: phiên bản của bạn là Θ (n), phiên bản này là Θ (n).
Và thực tế, đó không thực sự là cách bạn sẽ viết nó, vì, vì dù sao, Kernel#puts
cũng đã thực hiện hành vi đó. Vì vậy, những gì bạn sẽ thực sự ghi là này
puts a
a.clear
hoặc có lẽ đây
a.tap(&method(:puts)).clear
[Lưu ý: một cuối cùng này không phải là 100% tương đương. Nó in một dòng mới cho một mảng trống, tất cả những cái khác không in được gì.]
Đơn giản. Thông thoáng. Ngắn gọn. Biểu cảm. Nhanh.
so sánh với:
while (i = a.shift) do; puts i ; end
Tôi thực sự đã phải chạy mà nhiều lần để được 100% rõ ràng những gì nó làm.
Câu hỏi hay! –