为什么在Ruby中学习元编程和特殊类很重要?

8

我目前正在尝试 Ruby 和 Rails,其中在教程和书籍中遇到了一些关于元编程的部分。很多人提到它是 Ruby 的一个必不可少的组成部分,但他们并没有详细解释。似乎元编程是 Ruby 程序员的最后一块领地。作为一个 .NET 背景下的程序员,我很难理解为什么它被认为是如此有用。

  • 使用元编程有哪些好处?
  • 什么是特殊类(eigenclass),它与单例模式有何不同?
  • 在什么情况下通常会使用元编程?
  • 在使用代码修改其他代码的行为时,尤其是不属于你自己的代码时,有哪些伦理方面的考虑?
2个回答

17
  • 使用元编程有哪些好处?

    使用元编程可以创建比不使用更具表现力的API(例如,ActiveRecord使用元编程根据表的列名定义访问器方法,因此您可以像person.age这样编写代码,而不是像person.read_attribute("age")这样写,其中person是一个Active Record对象,而people表中有一个名为age的列),并且您可以以比通常更少的代码完成一些任务。

  • 什么是特殊类(eigenclass),它与单例(singleton)有何区别?

    在Ruby语言中,“特殊类”和“单例类”这两个术语可以互换使用。

  • 在哪些情况下使用元编程很常见?

    在需要大量样板代码或创建DSL时使用元编程。

    使用案例示例 1:

    例如,不要编写类似以下样板代码:

    class Foo
      def bar
        @bar
      end
    
      def bar=(b)
        @bar = b
      end
    
      def baz
        @baz
      end
    
      def baz=(b)
        @baz = b
      end
    end
    
    你可以使用元编程方法attr_accessor来编写更短的代码,它会自动定义基于你提供的参数的getter和setter方法的名称:
    class Foo
      attr_accessor :foo, :bar
    end
    

    如果标准库中不存在attr_accessor,你可以像这样自己定义它(让你了解Ruby元编程的样子):

    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
    

    结束

  • 在使用代码修改其他代码的行为,特别是不属于你的代码时,有哪些伦理上的影响?

    没有。


1
+1我真的很喜欢attr_accessor的例子,因为它展示了强大的元编程能力的重要好处:元编程使语言本身保持简单。在另一种语言中,attr_accessor很容易成为一个独立的语言构造(相关:C#中的属性等)。在Ruby中,它只是另一个方法。 - Mladen Jablanović
好的回答。虽然在Ruby中,eigenclass和singleton class意思相同,但后者现在是首选术语,因为存在方法singleton_classsingleton_methodsdefine_singleton_method - Marc-André Lafortune

5

元编程有其适用的时间和场合。我认为它在Ruby书籍中被广泛提及,是因为人们喜欢展示Ruby在其他语言无法胜任的领域所能做到的。

元编程就像不知道日语中“汉堡”或者“面条汤”的单词,但是知道“这个请”(“kore o kudasai”),并且能够在菜单上指出想要的食品一样。它提供了更多的灵活性,但你需要更多的上下文来确切地知道正在处理什么。

如果你正在创建ActiveRecord,它允许你进行find_by_foo操作,那么元编程就是有意义的。

如果你正在编写一个突变测试库,例如zombie-chaser,或者一个对Ruby的不同实现进行特征测试的应用程序,例如Small Eigen Collider,那么元编程就是有意义的。

然而,如果你正在编写一个应用程序,那么通常不应该进行元编程,而是进行编程。例如,如果您在应用程序中使用了instance_variable_set,那么这更像是一种代码异味,而不是您熟练程度的指标。
相关问题包括https://stackoverflow.com/questions/1236191/what-will-i-learn-from-metaprogramming-rubyRuby metaprogramming online tutorialMetaprogramming how much is too much?
我真的推荐书籍《Metaprogramming Ruby》,因为它不仅教授元编程,还教授Ruby的工作原理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接