Vào khoảng tháng 2, sau khi mình post cái rice v3.5.0 xong mình hứa là sẽ hướng dẫn mọi người cách dùng Ruby như một cái Shell. Ban đầu chỉ định là một bài viết nhỏ xong nở ra thành hẳn một trang web luôn! Xong cộng với thi thố ở trường và việc này việc kia nữa nên mãi đến bây giờ mình mới quay lại viết blog... Vậy nên xin lỗi và cảm ơn mọi người vì đã chờ đợi theo dõi blog của mình, mình sẽ cố gắng chăm chỉ viết blog hơn!
Quay trở lại Ruby. Như đã đề cập, cái trang web mà mình tạo ra để hướng dẫn mọi người cách dùng Ruby trong Shell là Ruby on Shell, nó rất hoàn thiện rồi và mọi người có thể vào đọc và nghiên cứu luôn. Bài blog này sẽ tập trung vào cách mình tìm ra sức mạnh của Ruby và quá trình mà mình tạo ra Ruby on Shell.
Cách mình đến với Ruby
Hồi đấy mình là một cậu bé ngây thơ, nghĩ rằng mình chỉ nên làm chủ một ngôn ngữ lập trình và dùng nó cho tất cả mọi thứ (và ngôn ngữ ấy là Python, một lựa chọn rất normie...). Mình dùng Xonsh (tóm tắt thì nó là sự kết hợp của Python và Bash) làm shell chính một thời gian, trải nghiệm tương tác với nó khá tốt nhưng scripting trên Xonsh hơi khó chịu. Vì off-side rule và list comprehension của Python nên mình khó có thể scripting ngắn gọn như mong muốn được.
Mình muốn một ngôn ngữ lập trình hẳn hoi như Python, Perl hoặc Lua nhưng với khả năng scripting tốt như Nushell hoặc Elvish.
Rồi một hôm mình thấy dòng này trên một bài viết của Xah Lee về list comprehension:
(0..9).select{|n| n.even?}.map{|n| 2*n}
Hãy để ý rằng đây không phải là list comprehension, bởi vì nó không dùng syntax đặc biệt, nhưng nó vẫn làm được
map(f, filter(list,predicate))
theo phong cách Ruby.
Mình có thấy cụ Xah Lee đề cập đến Ruby vài lần rồi, nhưng đấy là lần đầu tiên mình thấy code Ruby và đọc được là nó làm gì. Syntax của nó rất gọn, mình cảm giác là mình có thể scripting trên ngôn ngữ này một cách dễ dàng. Và đúng thế thật, mình đã đi sâu vào lý do vì sao Ruby là một lựa chọn hoàn hảo cho shell scripting trong Ruby on Shell nên mình sẽ không lặp lại nữa.
Đây là một vài cảm nghĩ của mình về Ruby trước khi chuyển sang phần tiếp theo:
- Mình có tia thấy Lua một thời gian và còn tìm thấy một shell giống kiểu Xonsh nhưng lấy Lua làm lõi (Hilbish). Nhưng chưa ưng Lua lắm vì mặc dù nó nhanh, nhẹ, đơn giản... Syntax của nó vẫn khá dài dòng và không dễ dàng nối hàm từ trái sang phải như Ruby hoặc các shell được.
- Hiện tại không có ngôn ngữ nào để vừa chạy Ruby vừa lệnh shell như Xonsh nên cách mà mình dùng Ruby trong terminal là:
- Dùng một POSIX shell làm shell chính và gán một phím tắt để chuyển sang Ruby để scripting.
- Trong Ruby có syntax để gọi lệnh shell một cách dễ dàng rồi (bọc lệnh bằng backticks) nên cứ thế mà shell script thôi.
Quá trình tạo ra Ruby on Shell
Không khó khăn nhưng rất tốn thời gian:
- Lập danh sách các công cụ CLI phổ biến: Mình tìm nó từ tài liệu về chuẩn POSIX, danh sách các công cụ trong Toybox và một số nguồn khác nữa. Xong tổng hợp hết lại và xem qua tất cả các công cụ xem nó làm gì và nó có nên ở trong danh sách không.
- Tìm giải pháp thay thế trong Ruby: Một lần nữa đi qua tất cả các công cụ trong danh sách, tìm hàm hoặc thư viện tương tự trong Ruby và ghi chép nó lại. Hầu hết mình chỉ cần nối một cái link đế API, nhưng một số thì phải viết hướng dẫn hẳn hoi.
- Xây lên một cái trang web hẳn hoi: Mặc dù đây là phần khó nhất của dự án, mình chỉ tốn chưa đến một tuần để dụng frontend cho nó... Và tầm hai tuần để dặn viết phần mở đầu.
Tuy vất vả nhưng sau cùng nó rất đáng, quá trình này giúp mình tăng sự hiểu biết về Ruby hơn và giờ mình đã có một cái cheat-sheet khá hữu dụng.
Tương lai
Hiện tại mình đang làm một dự án tên là Shell on Ruby để giúp scripting và dùng lệnh shell trong Ruby tiện hơn nữa.
Mình cũng thỉnh thoảng đá qua Crystal, syntax của nó giống Ruby ~90%, nhanh hơn và có nhiều thiết kế tốt hơn Ruby nhưng có vẽ scripting trên nó sẽ không tiện bằng.
Và đó là tất cả, mình sẽ tiếp tục phiêu lưu trên con đường xây dựng ra một môi trường scripting hoàn hảo. Hẹn gặp lại trong những blog tới đây.