2012-10-07 38 views
5

Tôi mới dùng Ocaml và cố gắng viết một số ứng dụng mẫu nhỏ. Tôi đang sử dụng ocamlc phiên bản 3.11.2 trong Linux Ubuntu 10.04. Tôi muốn biên dịch hai tệp:Biên soạn nhiều tệp Ocaml

a.ml 
b.ml 

Tệp b.ml sử dụng định nghĩa từ a.ml. Theo tôi hiểu, tôi có thể sử dụng ocamlc -c để chỉ thực hiện biên dịch. Tôi có thể gọi ocamlc lần cuối cùng khi tôi có tất cả các tệp .cmo để liên kết chúng với tệp thực thi. Ngoài ra, khi biên dịch một tệp sử dụng các định nghĩa từ một tệp khác, tôi phải thông báo cho trình biên dịch trong đó tệp .cmi để tìm các định nghĩa bên ngoài.

Vì vậy, ý tưởng của tôi là sử dụng:

ocamlc -i -c a.ml > a.mli 
ocamlc -c a.mli b.ml 
ocamlc -o b a.cmo b.cmo 

Các công trình bước đầu tiên và tạo ra file a.mlia.cmo, nhưng khi chạy bước thứ hai tôi nhận được

File "b.ml", line 1, characters 28-31: 
Error: Unbound value foo 

nơi foo là một hàm được định nghĩa trong a.ml và được gọi trong số b.ml.

Vì vậy, câu hỏi của tôi là: làm cách nào tôi có thể biên dịch từng tệp nguồn một cách riêng biệt và chỉ định giao diện được nhập trên dòng lệnh? Tôi đã được tìm kiếm trong các tài liệu và theo như tôi có thể hiểu tôi phải xác định các tập tin .mli được bao gồm, nhưng tôi không biết làm thế nào.

EDIT

Dưới đây một số chi tiết. Tập tin a.ml chứa các định nghĩa

let foo = 5;; 

tập tin b.ml chứa các biểu

print_string (string_of_int foo)^"\n";; 

Các ví dụ thực tế là lớn hơn nhưng với những tập tin này tôi đã có lỗi Tôi đã báo cáo ở trên.

EDIT 2

Tôi đã chỉnh sửa tập tin b.ml và thay thế foo với A.foo và các công trình này (foo có thể nhìn thấy trong b.ml mặc dù tôi có một lỗi biên dịch mà không phải là quan trọng đối với câu hỏi này). Tôi đoán rằng việc viết các tệp .mli của riêng tôi rõ ràng hơn, như được đề xuất bởi

+1

bạn có mở A bằng B ?, vì điều này không có ý nghĩa. –

+0

No. Tôi có phải định nghĩa một mô-đun trong A và mở nó trong B không? Tại thời điểm này tất cả các định nghĩa trong A là toàn cục (tôi không có mô-đun). – Giorgio

+1

Có một mô-đun tiềm ẩn cho mỗi tệp OCaml. Vì vậy, tệp của bạn 'a.ml' định nghĩa một mô-đun có tên' A'. –

Trả lời

5

Sẽ rõ ràng hơn nếu bạn đã hiển thị mã không hoạt động. Tuy nhiên, như Kristopher đã chỉ ra, vấn đề có thể xảy ra nhất là bạn không chỉ định module nào foo đang ở. Bạn có thể chỉ định rõ ràng mô-đun, như A.foo. Hoặc bạn có thể open A và chỉ sử dụng tên foo.

Ví dụ nhỏ không quan trọng, nhưng đối với một dự án lớn, bạn nên cẩn thận không sử dụng open quá tự do. Bạn muốn tự do sử dụng tên tốt trong các mô-đun của bạn, và nếu bạn mở quá nhiều tên, các tên tốt có thể xung đột với nhau.

5

Trước tiên hãy khắc phục sự cố unbound value, như được giải thích bởi câu trả lời của Jeffrey. Đây là nhận xét về các lệnh bạn đang sử dụng.

Phân tích biên dịch theo nhiều bước là cách hay để hiểu những gì đang diễn ra. Nếu bạn muốn viết a.mli của riêng mình, nhiều khả năng để ẩn một số giá trị của mô-đun A, thì lệnh của bạn ocaml -i -c a.ml > a.mli là cách tốt để lấy phiên bản đầu tiên của tệp này và sau đó chỉnh sửa nó. Nhưng nếu bạn không chạm vào a.mli, sau đó bạn không cần phải tạo ra nó: bạn cũng có thể trực tiếp nhập

ocamlc -o foo a.ml b.ml 

đó sẽ sản xuất a.cmo, b.cmo và exectuable foo.

(Nó cũng sẽ tạo ra a.cmi, là phiên bản được biên dịch của a.mli, mà bạn nhận được bằng cách phát hành ocamlc -c a.mli. Tương tự như vậy nó cũng sẽ tạo ra b.cmi).

Lưu ý rằng đơn đặt hàng quan trọng: bạn cần cung cấp a.ml trước b.ml trên dòng lệnh. Bằng cách này, khi biên dịch b.ml, trình biên dịch đã thấy a.ml và biết nơi để tìm mô-đun A.


Một số chi tiết nhận xét:

  • Bạn nói đúng trong "Theo như tôi hiểu" đoạn của bạn.
  • bạn không thực sự bao gồm một file riêng biệt, nó giống như nhập khẩu bằng Python: các giá trị của mô-đun A có sẵn, nhưng dưới cái tên A.foo. Nội dung của a.ml chưa được sao chép thành b.ml, đúng hơn là giá trị của mô-đun A, được xác định trong a.ml và phiên bản được biên dịch a.cmo đã được truy cập.
  • nếu bạn đang sử dụng module này A trong b.ml, bạn có thể vượt qua bất cứ điều nào sau đây trên dòng lệnh trước b.ml:
    • a.mli, sẽ được biên dịch vào a.cmi
    • a.cmi nếu bạn đã đã được biên soạn a.mli thành a.cmi
    • a.ml hoặc phiên bản được biên dịch a.cmo nếu bạn không cần viết riêng a.mli, tức là nếu giao diện mặc định của mô-đun A phù hợp với bạn. (Giao diện này đơn giản là mọi giá trị của a.ml).