Học cách dùng gem Ruby-progessbar: Thư viện hiển thị progress bar trong Ruby

Tram Ho

Gần đây mình thường hay phải chạy mấy cái rake task siêu to khổng lồ, ngồi nhìn cái màn hình log ra mấy dòng chữ nhạt nhẽo cũng chán. Nhẩm nghĩ liệu có cái thư viện nào giúp mình hiển thị trạng thái của tiến trình đang chạy lên màn hình không, ấy thế là mình khám phá ra cái thư viện hay ho này. Ruby-progressbar là một lựa chọn khá tuyệt vời cho việc hiển thị progress chạy của một hàm, một job hay một task bất kỳ trong Ruby. Nó có một số ưu điểm như sau:

  • là gem lâu đời và vẫn dùng tốt từ 2008 đến nay
  • có test suite đầy đủ
  • không có dependencies
  • được sử dụng bởi rất nhiều dự án mã nguồn mở
  • trải nghiệm tốt
  • có nhiều contributors và được maintain thường xuyên

Hãy bắt đầu tìm hiểu và cùng trải nghiệm nó thôi!

Cài đặt

Bạn có thể cài luôn vào gem

sau đó trong script đặt thêm require 'ruby-progressbar'

hoặc đặt vào Gemfile

Sử dụng như nào?

Cách khởi tạo đơn giản thôi.

Dòng lệnh này tạo một cái progress bar đơn giản bắt đầu từ 0 với độ đo lớn nhất là 100, sẽ hiển thị trên màn hình như thế này:

Ngoài ra bạn có thể có nhiều option để tạo một progress bar, ví dụ:

Cái này sẽ output ra như sau:

Dưới đây là mô tả chi tiết về các options bạn có thể sử dụng:

——-Tùy chọn ——————–Mặc địnhMô tả
:titleProgressTiêu đề của progress bar
:total100Tổng khối lượng công việc cần hoàn thành
:starting_at0Điểm khởi đầu của progress bar. Khi gọi #reset thì sẽ trở về giá trị này
:progress_mark=Kí hiệu đánh dấu lượng progress đã hoàn thành
:remainder_markkhoảng trắngKí hiệu đánh dấu phần progress còn lại phải hoàn thành
:format%t: |%B|Format string dùng để format cách hiển thị của progress bar
:lengthchiếm full độ rộng có thể nếu không thì bằng 80Độ rộng của progress bar hiển thị trên màn hình
:output$stdoutTất cả output sẽ được truyền tới object này (standard output). Có thể là bất cứ object nào có 4 phương thức .print .flush .tty? .puts

Cập nhật progress

Biết cách tạo ra nó rồi, vậy làm thế nào để cập nhật progress của bar? Dưới đây là một vài phương thức mà thư viện cung cấp:

——-Phương thức ——Mô tả
#incrementTăng progress lên 1 đơn vị. Đây là cách thường dùng nhất
#decrementGiảm progress xuống 1 đơn vị
#progress+=Cho phép tăng progress một khối lượng nhất định
#progress-=Cho phép giảm progress một khối lượng nhất định
#progress=Đặt progress ở một giá trị chỉ định. Thường ta chỉ dùng cái này để test thôi.
#total=Thay đổi tổng khối lượng cần hoàn thành của progress bar

Cái này có thể là giá trị gì cũng được (kể cả nil) nhưng không được bé hơn progress hiện tại

Có thể minh họa bằng hình ảnh như sau:

Changing Progress Animation

Stopping

Bạn có thể dừng progress bar bằng một trong bốn cách sau:

——-Phương thức——–Description
#finishDừng progress bar ngay lập tức. Vị trí của progress sẽ bằng với vị trí kết thúc
#stopDừng progress bar ngay lập tức . Vị trí của progress giữ nguyên
#pauseSẽ dừng progress bar giống như stop nhưng cho phép quay lại chạy bằng cách gọi #resume.

Lưu ý: Elapsed Time và Estimated Time sẽ dừng khi progress bar ở trạng thái paused.

#resetSẽ dừng progress bar bằng cách reset lại tất cả các thông tin của nó về thời điểm ban đầu

Quan sát minh họa:

Finishing

Mặc định, bạn sẽ thấy thanh hiển thị kết thúc khi progress đạt giá trị bằng với total. Nếu không muốn progress bar tự động kết thúc, hãy truyền option autofinish: false khi khởi tạo.

Refreshing

Nếu bạn cần hiển thị lại progress bar để cho người dùng trải nghiệm real-time hơn, hãy dùng #refresh. #refresh không tác động đến vị trí hiện tại của progress mà sẽ cập nhật log thời gian Elapsed time và Estimated time.

Tiến trình không rõ điểm kết thúc


Đôi khi bạn sẽ gặp trường hợp phải thực hiện một công việc mà không biết rõ tổng khối lượng của nó là bao nhiêu. Điều này có thể xảy ra khi bạn đang download một đống files hoặc khi bạn đang xử lý một tập các jobs chưa được load hoàn toàn.

Những lúc như thế bạn có thể set giá trị của totalnil và tiếp tục tăng progress của bar nhưu bình thường. Lúc này thanh hiển thị sẽ cho bạn thấy progress đang chạy nhưng không rõ là bao nhiêu và bao giờ sẽ hoàn thành. Ví dụ

sẽ output ra giống giống như hình phía trên.

Tại bất cứ thời điểm nào khi bạn biết được giá trị total là bao nhiêu, có thể set cho nó bằng phương thức

Lúc này progress bar sẽ chuyển thành trạng thái như này:

Logging

Khi sử dụng progress bar, bạn có thể sẽ muốn log một cái output nào đó cho người dùng. Nếu bạn thử sử dụng một câu lệnh puts, bạn sẽ thấy rằng nó viết đè lên thanh hiển thị. Ví dụ khi bạn puts "hello" sau khi một progress được chạy, màn hình có thể trông như này:

Điều này xảy ra bởi progressbar phải luôn vẽ lại nó mỗi lần progress thay đổi. Đây là giới hạn của việc output trên terminal. Để có thể tránh điều này, hãy sử dụng phương thức #log .

Phương thức #Log sẽ tự động clear progress bar, in text rồi vẽ lại bar ở dòng tiếp theo. Vì vậy nếu sử dụng phương thức này, bạn sẽ luôn chỉ nhìn thấy một thanh hiển thị duy nhất trên màn hình mà thôi.

Kết luận

Trên đây là kha khá những gì mà mọi người có thể sử dụng để ứng dụng gem Ruby-progressbar tạo một script cool ngầu trong lập trình với Ruby. Thông tin chi tiết hơn hãy tham khảo Ruby-progressbar Wiki . Happy coding!

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo