Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Dịch, chạy, và reload chương trình Erlang
Người kinh nghiệm với ngôn ngữ thủ tục như Pascal, C và ngôn ngữ hướng đối tượng như C++, Java, Ruby khi mới học viết Erlang sẽ thấy rất khác, vì nó là ngôn ngữ hàm. Ngay cả cách chạy chương trình Erlang cũng rất lạ.
Bài viết này hi vọng giúp giải tỏa bối rối về cái sự lạ chạy chương trình Erlang. Ngoài ra, bài viết "bonus" thêm quả dịch và reaload chương trình.
Chạy
Khi chương trình C chạy, hàm main() sẽ chạy trước tiên trong một tiến trình (process). Tiến trình này có thể đẻ ra (spawn) các tiến trình hoặc luồng (thread) con khác. Khi tiến trình main() kết thúc là lúc chương trình kết thúc. Hàm main() chính là điểm vào (entry point) của chương trình C.
Khi viết chương trình Erlang, để ý sẽ thấy không hề có hàm giống như main(). Vậy khi chạy chương trình, hàm nào sẽ chạy trước tiên? Bối rối thật!
Rà soát lại về mặt thuật ngữ, rõ ràng chương trình Erlang bình thường được khai báo ở đầu tập tin .erl là "module" (nếu ai có học Pascal, thì nhớ lại là ở đầu tập tin .pas có dòng khai báo là "program"). Vậy những người thiết kế ra Erlang thật ra đâu có cố tình gây ra bối rối trên.
Có thể hiểu Erlang module chẳng qua chỉ là thư viện .dll trên Windows hoặc .so trên Linux mà thôi. Module chẳng qua chỉ là tập hợp các hàm, chương trình muốn chạy hàm nào trước thì chạy. Gọi module là chương trình là không chính xác.
Tóm lại chương trình thật sự nằm ở đâu? Trả lời:
- Chương trình là lệnh erl.
- Khi chạy lệnh erl, tiến trình chính được chạy. Khi tiến trình chính kết thúc thì chương trình mới kết thúc.
- Các tiến trình khác có thể được tạo ra sau đó. Các tiến trình này chạy song song với tiến trình chính, và việc chúng kết thúc không làm tiến trình chính kết thúc.
Về lệnh erl:
- Khi chạy lệnh erl không có tham số gì, nó sẽ chạy ở chế độ tương tác. Lúc này ngoài tiến trình chính, còn có thêm tiến trình xử lí việc tương tác bàn phím với người dùng. Lúc này, gọi hàm init:stop/0 hoặc q/0 sẽ làm tiến trình chính kết thúc, và chương trình cũng kết thúc.
- Để tiến trình xử lí tương tác bàn phím không tự động được tạo ra, cần chạy lệnh erl với tham số -noshell.
- Để tự động tạo tiến trình, rồi chạy lần lượt các hàm trong các module nào đó, chạy lệnh erl với tham số -s. Ví dụ: erl --noshell -s my_module my_function -s init stop.
- Để hiểu thêm, hãy đọc tài liệu về lệnh erl.
Đến đây, có lẽ bối rối đã được giải tỏa xong. Để ý thêm:
- Muốn viết chương trình Erlang thật sự, cần tìm hiểu cái gọi là application.
- Cách tiếp cận khi học Erlang ngược với bình thường. Thường ta học viết chương trình trước, thư viện sau. Đằng này với Erlang ta học viết thư viện trước, chương trình sau.
Dịch
Có nhiều cách, cách dễ nhất khi muốn dịch x.erl là gõ lệnh erlc x.erl
. Để dịch nhiều tập tin, chỉ cần học cách viết Makefile của C hay Rakefile của Ruby v.v. để kết hợp với lệnh erlc trên là được. Tuy nhiên khi có nhiều tập tin thì cách sạch sẽ nhất là:
- Tạo 3 thư mục: include để chứa .hrl, src để chứa .erl, ebin để chứa .beam
- Tạo 2 tập tin: Emakefile và Makefile
- Emakefile (mỗi /* ứng với một cấp thư mục trong src):
{'src/*', [ debug_info, {i, "include"}, {outdir, "ebin"} ]}. {'src/*/*', [ debug_info, {i, "include"}, {outdir, "ebin"} ]}. {'src/*/*/*', [ debug_info, {i, "include"}, {outdir, "ebin"} ]}.
- Makefile (chú ý bắt buộc phải dùng tab để thụt đầu dòng trong trong Makefile!):
compile: erl -make clean: rm -rf ebin/*.beam
Bây giờ chỉ cần make compile
là xong.
Reload
Erlang có tính năng reload module ngay khi chương trình đang chạy. Nghĩa là khi chương trình đang chạy, có thể sửa mã nguồn của module nào đó, dịch lại, rồi reload module vào trong chương trình. Nhờ tính năng cực kì lợi hại này, có thể cập nhật chương trình ngay khi nó đang chạy mà không cần khởi động lại. Để reload:
- Khi có Emakefile, ở màn hình Eshell, gõ lệnh:
make:all([load]).
- Nếu không có, sau khi dịch lại xong, ở màn hình Eshell gõ lệnh:
l(tên module).
Tham khảo







