2011-08-23 25 views
8

Tôi hiện đang thử nghiệm với Ruby và Rails, và tôi đã nhấn một vài phần trong hướng dẫn và sách về lập trình meta. Nhiều người đề cập rằng nó là một thành phần thiết yếu của Ruby nhưng chúng không thực sự đi sâu vào chi tiết. Nó giống như metaprogramming là biên giới cuối cùng cho các lập trình viên Ruby. Đến từ một nền .NET Tôi đang đấu tranh để hiểu tại sao nó được cho là rất hữu ích.Tại sao điều quan trọng là phải tìm hiểu về lập trình meta và eigenclasses trong Ruby?

  • Lợi ích nào có được khi sử dụng lập trình meta?
  • eigenclass là gì và khác biệt gì so với singleton?
  • Trong những tình huống nào đang sử dụng lập trình meta phổ biến?
  • Ý nghĩa đạo đức nào có xung quanh việc sử dụng mã để sửa đổi hành vi của mã khác, đặc biệt là mã không phải là mã của riêng bạn?

Trả lời

16
  • Lợi ích nào có được khi sử dụng lập trình meta?

    Bạn có thể tạo các API biểu cảm hơn mà không có nó (ví dụ ActiveRecord sử dụng lập trình meta để xác định phương pháp accessor dựa trên tên cột của một bảng, vì vậy bạn có thể viết những thứ như person.age thay vì một cái gì đó giống như person.read_attribute("age"), nơi person là một đối tượng ghi lại hoạt động và bảng people có một cột có tên là age) và bạn có thể thực hiện một số thứ với mã ít hơn đáng kể so với cách khác.

  • eigenclass là gì và khác biệt gì so với singleton?

    Thuật ngữ "eigenclass" và "singleton class" được sử dụng thay thế cho nhau trong bối cảnh của ruby.

  • Trong những tình huống nào đang sử dụng lập trình meta phổ biến?

    Trong trường hợp bạn muốn có nhiều mã đĩa nồi hơi hoặc khi tạo DSL.

    Ví dụ về trường hợp sử dụng 1:

    Thay vì viết một cái gì đó đang nồi hơi-tấm như thế này:

    class Foo 
        def bar 
        @bar 
        end 
    
        def bar=(b) 
        @bar = b 
        end 
    
        def baz 
        @baz 
        end 
    
        def baz=(b) 
        @baz = b 
        end 
    end 
    

    Bạn có thể viết mã ngắn hơn nhiều này sử dụng phương pháp lập trình meta attr_accessor, có thể tự động xác định phương thức getter và phương pháp setter với tên dựa trên các đối số bạn cung cấp cho nó:

    class Foo 
        attr_accessor :foo, :bar 
    end 
    

    Nếu attr_accessor không alr eady tồn tại trong thư viện chuẩn, bạn có thể định nghĩa nó cho mình như thế này (để cung cấp cho bạn một ý tưởng gì Lập trình meta trong ruby ​​trông tương tự):

    class Module 
        def attr_accessor(*variable_names) 
        variable_names.each do |variable_name| 
         define_method(variable_name) do 
         instance_variable_get("@#{ variable_name }") 
         end 
    
         define_method("#{ variable_name }=") do |value| 
         instance_variable_set("@#{ variable_name }", value) 
         end 
        end 
        end 
    

    cuối

  • gì ý nghĩa đạo đức đang có xung quanh sử dụng mã để sửa đổi hành vi của mã khác, đặc biệt là mã không phải là mã của riêng bạn?

    Không có.

+1

+1 Tôi thực sự thích ví dụ 'attr_accessor', vì nó cho thấy lợi ích quan trọng của khả năng lập trình siêu lập trình mạnh mẽ: lập trình meta giúp ngôn ngữ trở nên đơn giản. 'attr_accessor' có thể dễ dàng là một ngôn ngữ riêng biệt được xây dựng bằng ngôn ngữ khác (liên quan: các thuộc tính trong C#, v.v.). Trong Ruby, nó chỉ là một phương pháp khác. –

+0

Câu trả lời hay. Trong khi đúng là lớp eigenclass và singleton có nghĩa là cùng một thứ trong Ruby, thì thứ hai bây giờ là thuật ngữ ưa thích, như được chỉ ra bởi sự tồn tại của các phương thức 'singleton_class',' singleton_methods' và 'define_singleton_method'. –

4

Có thời gian và địa điểm để lập trình meta. Tôi nghĩ rằng nó được đề cập rất nhiều trong sách Ruby bởi vì mọi người thích thể hiện những gì Ruby có thể làm mà các ngôn ngữ khác cũng không thể làm được.

Lập trình meta giống như không biết từ tiếng Nhật cho "burger" hoặc "soup soup", nhưng biết tiếng Nhật cho "this please" ("kore o kudasai") và có thể chỉ vào mục trên thực đơn. Nó cho phép sự linh hoạt hơn, nhưng bạn cần thêm ngữ cảnh để biết chính xác những gì đang được thực hiện.

Nếu bạn đang tạo ActiveRecord, cho phép bạn thực hiện find_by_foo, thì lập trình meta có ý nghĩa.

Nếu bạn đang viết thư viện thử nghiệm đột biến như zombie-chaser hoặc ứng dụng thử nghiệm đặc tính kiểm tra các triển khai khác nhau của Ruby, chẳng hạn như Small Eigen Collider, thì lập trình meta có ý nghĩa.

Tuy nhiên, nếu bạn đang viết một ứng dụng, thì bạn thường không nên lập trình meta, nhưng chỉ đơn thuần là lập trình. Ví dụ: nếu bạn đang sử dụng instance_variable_set trong ứng dụng của mình, thì đó là mùi mã hơn là dấu hiệu cho thấy bạn thành thạo như thế nào.

Các câu hỏi liên quan bạn có thể muốn đọc bao gồm https://stackoverflow.com/questions/1236191/what-will-i-learn-from-metaprogramming-rubyRuby metaprogramming online tutorialMetaprogramming how much is too much?.

Tôi thực sự khuyên bạn nên cuốn sách "Metaprogramming Ruby", bởi vì nó không chỉ dạy cho bạn lập trình meta, nhưng cách Ruby hoạt động.

+0

+1 cho ví dụ tiếng Nhật. Hoàn hảo! – rubish

Các vấn đề liên quan