2010-05-28 21 views
11

Tôi đang cố gắng xác định toán tử của riêng mình ở Io và tôi đang gặp khó khăn. Tôi có một đối tượng:Làm cách nào để xác định toán tử của riêng tôi bằng ngôn ngữ lập trình Io?

MyObject := Object clone do(
    lst := list() 
    !! := method(n, lst at(n)) 
) 

Nhưng khi tôi gọi nó, như thế này:

x := MyObject clone do(lst appendSeq(list(1, 2, 3))) 
x !! 2 

Nhưng tôi nhận được một ngoại lệ mà tranh luận từ 0 đến ở không phải là con số không. Làm thế nào tôi có thể sửa chữa?

Trả lời

14

Vâng, có một vấn đề trong mã của bạn. Nói một cách đơn giản, bạn chưa thêm !! vào bảng toán tử. Tôi sẽ cung cấp cho bạn một chút về điều này.

Các toán tử trong Io bị xáo trộn trước khi AST được tạo. Điều này có nghĩa, rằng chúng ta phải duy trì một danh sách các toán tử đã biết với các mức ưu tiên nhất định để biết cái nào ràng buộc chặt chẽ hơn những cái khác. Chúng tôi làm điều này trong "OperatorTable". Nếu bạn đang ở trong REPL, bạn có thể xem cách sử dụng nó bằng cách gõ "OperatorTable" vào REPL (không có dấu ngoặc kép). Điều này sẽ cung cấp cho bạn một danh sách các toán tử, (được tạo động, vì vậy các toán tử mới được thêm vào khi chúng được định nghĩa), cùng với các ví dụ về cách sử dụng từng loại toán tử. Có hai loại:

  1. khai thác Binary (1 + 2 ví dụ, được gọi đơn giản là "khai thác")
  2. khai thác Chuyển nhượng (a: = b ví dụ)

Vì vậy, trong ví dụ của bạn, mã của bạn là đúng; chúng ta không phải thay đổi bất cứ thứ gì ở đó. Tuy nhiên, chúng tôi đang thiếu một chút mã để làm cho hệ thống con phân tích cú pháp biết cách xử lý toán tử của bạn. Tôi sẽ cung cấp một ví dụ cho rằng bạn muốn nó liên kết chặt chẽ như phép nhân.

OperatorTable addOperator("!!", 3) 

Bây giờ, chúng ta có thể thấy điều này được xáo trộn bằng cách xây dựng thông điệp và xem cây của nó được thể hiện như thế nào. Một lần nữa trong REPL, nếu chúng ta gõ:

message(a !! b) 

Chúng ta sẽ thấy một cái gì đó như thế này:

==> a !!(b) 

Đây là giống như bất kỳ cuộc gọi phương pháp khác, nó phải tồn tại ở đâu đó hoặc nếu không bạn sẽ nhận được một lỗi. Bạn có thể sử dụng nó như nó được hiển thị ở trên (với dấu ngoặc đơn rõ ràng), hoặc bạn có thể sử dụng nó như thế nào bạn muốn trong câu hỏi ban đầu của bạn, mà không có dấu ngoặc đơn rõ ràng. Như với bất kỳ toán tử nào, bạn phải tuân thủ các quy tắc ưu tiên nếu bạn không sử dụng dấu ngoặc đơn rõ ràng, chỉ để bạn biết.

Hy vọng điều này sẽ trả lời câu hỏi của bạn.

+1

Cảm ơn câu trả lời của bạn, hữu ích khi biết. Tuy nhiên, tôi không hiểu tại sao "n" là nil trong tôi !! phương pháp. –

+3

Được rồi, chỉ cần đặt, trong Io, chỉ có các hàm (có nghĩa là, các phương thức được triển khai trong mã C lấy các đối số cụ thể tại các chỉ mục cụ thể) có yêu cầu rằng bạn phải cung cấp ít nhất N đối số. Khi một toán tử không được biết, nó không bị xáo trộn, có nghĩa là x ban đầu của bạn !! 2 được xem là: message (x !! 2) và không phải là tin nhắn (x !! (2)). Kể từ !! được định nghĩa trong mã Io với xử lý đối số mặc định, điều xảy ra là bất kỳ đối số nào không được cung cấp rõ ràng đều được điền bằng "nil". Đó là, các đối số được xác định, nhưng chúng trỏ vào nil. Đây là nguồn gốc của vấn đề của bạn. – jer

+0

+1 cho một câu trả lời kỹ lưỡng, cũng cho các miếng ngon về OperatorTable đại diện cho thứ tự ưu tiên. Tôi đã không nhận ra điều đó. – labyrinth

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