Tìm hiểu về metaprogramming và các phương thức meta programming thường gặp

Tram Ho

Mình vừa ôn lại một vài khái niệm chuyên sâu trong ruby sau một thời gian không đụng tới, hôm nay mình xin viết một bài về metaprogramming

Khái niệm Metaprogramming:

Theo Wikipedia:

Tóm tắt lại, metaprogramming là một kĩ thuật giúp code chúng ta linh hoạt hơn, động hơn. Nghĩa là nó sẽ cho phép định nghĩa các method và class trong thời gian runtime, giúp code ngắn gọn và tránh bị trùng lặp.

Các method thường gặp trong metaprogramming

Send

Bất kể khi nào bạn gọi một phương thức của một đối tượng, tức là bạn đang gửi một “message” đến đối tượng đó. Và “message” chính là tên của phương thức. Tham số đầu tiên chính là tên method mà mình muốn gọi, các đối số khác là các tham số truyền vào tương ứng với các tham số truyền vào của hàm mà mình đã định nghĩa bên dưới.
Ví dụ như sau:

respond_to?

Phương thức này sẽ trả về true nếu đối tượng đáp ứng với tên phương thức truyền vào, nó là một symbols (nếu bạn truyền string vào thì nó cũng sẽ tự convert sang symbol)

Tuy nhiên nếu viết như trên thì nó chỉ tìm được các method public mà thôi, để tìm được các method protected và private, thì các bạn phải truyền thêm tham số thứ 2 vào. ưu ý rằng tham số thứ hai của method respond_to? rất quan trọng ở đây, nó biểu thị rằng respond_to? có thể tìm tất cả các method mà phạm vị bao gồm cả các method protected và private
Trong ví dụ trên nếu dogs là một method private thì ta sẽ gọi như sau:

instance_eval

Mình viết lại đoạn code trên một xíu cho đầy đủ như sau:

Hiện tại mình đã gọi được method dogs để in ra tên của giống chó, nhưng giả sử trong trường hợp mình không muốn gọi đến method dogs, mình chỉ muốn biết cái instance variable name của object a nó là gì thôi, tức là tên của giống chó được truyền vào. Lúc này mình sẽ sử dụng instance_eval. Method này được gọi dưới dạng block hoặc string.

module_eval, class_eval

Những methods module_eval và class_eval được dùng trên các module và class chứ ko phải trên object. class_eval là 1 alias của module_eval.
Những method này được sử dụng để thêm/bớt giá trị của các class variables từ bên ngoài class đó.

Module_eval và class_eval có thể được dùng để thêm instance methods vào 1 module hoặc class. Mặc dù 2 method này có tên khác nhau nhưng chức năng thì giống hệt nhau.

Note: class_eval định nghĩa instance methods, còn instance_eval định nghĩa class_methods

method_missing

Method_missing là một phương thức mà ruby cho phép bạn truy cập vào bên trong một đối tượng và xử lý trong trường hợp bạn gọi tới một phương thức không tồn tại. Nó là một method được xây dựng sẵn của class BasicObject trong Ruby
Method_mising nhận 3 tham số:

  • Tham số đầu tiên là tên của phương thức mà bạn đang cố gọi tới
  • Tham số thứ hai là những đối số (*args) được truyền khi gọi tới phương thức đó
  • Tham số thứ ba là một block (&block) những tham số của phương thức Tham số thứ hai và ba có thể rỗng nếu phương thức gọi tới không tryền tham số

Tổng kết

Trên đây là bài giới thiệu tổn quan vể metaprogramming và một số method, sẽ còn rất nhiều method khác nữa nhưng trong phạm vi bài viết này mình chỉ viết một số method thường gặp khi làm dự án. Mong mọi người đóng góp ý kiến để bài viết được hoàn thiện!

Tài liệu tham khảo

http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_3.html

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo