2010-09-25 45 views
20

Tôi đã nghiên cứu các điểm tương đồng/khác biệt giữa các trình tạo Ruby và Python (được gọi là Enumerators trong Ruby), và cho đến nay tôi có thể nói chúng khá giống nhau.Máy phát điện Ruby và máy phát Python

Tuy nhiên, một sự khác biệt mà tôi đã nhận thấy là các Trình tạo Python hỗ trợ phương thức close() trong khi Trình tạo Ruby không. Từ các tài liệu Python, phương pháp close() được cho là thực hiện như sau:

Tăng một máy phát .Tại điểm dừng chức năng máy phát. Nếu chức năng máy phát điện sau đó nâng StopIteration (do xuất cảnh bình thường, hoặc do đã bị đóng cửa) hoặc GeneratorExit (bằng cách không thu hút sự ngoại lệ), lợi nhuận gần gọi của nó."

Có một lý do chính đáng tại sao của Ruby Enumerators không hỗ trợ phương pháp close()? Hay là một tình cờ thiếu sót?

tôi cũng phát hiện ra rằng Ruby Enumerators hỗ trợ một phương pháp rewind() chưa phát Python không ... là có một lý do cho điều này quá?

Cảm ơn

+0

Tò mò, nhưng tôi không hiểu bạn sẽ sử dụng điều này như thế nào: bạn có thể đưa ra ví dụ không? –

+5

@Andrew Vit: điều này có thể được sử dụng để gây ra các tài nguyên —các kết nối cơ sở dữ liệu, tệp, v.v. do máy phát điện giữ lại để được dọn sạch.Nó cũng sẽ ngăn chặn bất kỳ cuộc gọi nào nữa đến các phương thức 'next' hoặc' send' của nó từ các phần khác của mã. Bạn có thể gọi 'close', ví dụ, để chỉ ra từ một trong số một số người tiêu dùng để chỉ ra cho người khác rằng một giá trị mong muốn đã được tìm thấy. – intuited

+0

@intuited, là của Python 'close()' thực sự thường được sử dụng mặc dù? Tôi nghĩ rằng tôi đọc một nơi nào đó mà nó được coi là 'arcane' bởi cộng đồng python và không thực sự được sử dụng. – horseyguy

Trả lời

2

Máy phát điện dựa trên nền tảng xếp chồng, Số đếm của Ruby là thường là chuyên biệt (ở cấp độ thông dịch viên) và không dựa trên stack.

1

lớp sử dụng StopIteration Ruby Enumerator của nội bộ, xem How do Enumerators work in Ruby 1.9.1?

(nó chỉ quấn nếu bạn sử dụng nó trong một cho mỗi cuộc gọi). Vì vậy, tôi muốn nói rằng họ đang ở khá gần. Điều đó đang được nói, tôi không chắc chắn những gì một phương pháp gần trên một điều tra nên làm, chính xác ... dọn dẹp, có lẽ? (Máy phát điện của Python có thể sẽ được hưởng lợi từ một lưu ý tua lại trong Ruby, một số điều tra viên không trả lời để tua lại, vì vậy chúng nêu ra một ngoại lệ khi bạn gọi phương thức đó).

+2

cảm ơn câu trả lời của bạn. Nhưng 'StopIteration' là những gì python sử dụng quá - trong thực tế, Ruby đã lấy ý tưởng này từ Python hehe. Như Regards những gì một 'close()' có thể làm, nhìn vào nhận xét của intuited cho câu hỏi của tôi (ở trên). – horseyguy

+0

Vâng Enyator ruby ​​1.9.x về cơ bản đã đưa nó vào phù hợp với Máy phát điện Python (mặc dù bạn cũng có thể chỉ cần sử dụng một khối trong Ruby để mô phỏng một máy phát điện, thực sự). – rogerdpack

6

Điều này documentation for the rewind method hơi khan hiếm chi tiết. Nhưng để "bắt đầu lại" các máy phát điện sẽ phải làm một trong hai điều:

  • nhớ ra trọn vẹn của nó, lặp lại đầu ra rằng một khi rewound, sau đó tiếp tục những gì nó đã làm trước
  • reset trạng thái nội bộ của mình theo cách khiến cho cùng một đầu ra được lặp lại mà không có các tác dụng phụ không mong muốn khác

Điều thứ hai không phải lúc nào cũng có thể được; ví dụ, nếu bộ tạo phát ra bộ đệm byte từ mạng, đầu ra không hoàn toàn là một hàm của trạng thái bên trong. Nhưng bất kỳ máy phát điện nào sử dụng kỹ thuật đầu tiên nhất thiết phải xây dựng một bộ đệm lớn hơn và lớn hơn trong bộ nhớ khi nó được sử dụng. Máy phát điện như vậy cung cấp ít lợi ích hiệu suất hơn danh sách.

Vì vậy, tôi kết luận rằng phương pháp Ruby rewind phải là tùy chọn và không phải lúc nào cũng được hỗ trợ bởi lớp điều tra cụ thể. Vì vậy, nếu các nhà thiết kế Python có giá trị Liskov substitution principle, điều đó sẽ dẫn họ không yêu cầu một phương thức như vậy trong tất cả các máy phát.

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