我目前正在尝试使用 Ruby 和 Rails,并且我已经阅读了有关元编程的教程和书籍中的一些部分。许多人提到它是 Ruby 的重要组成部分,但他们并没有真正深入细节。就好像元编程是 Ruby 程序员的最后一道防线。来自 .NET 背景,我很难理解为什么它如此有用。
- 使用元编程有什么好处?
- 什么是特征类,它与单例有何不同?
- 在什么情况下使用元编程很常见?
- 使用代码来修改其他代码的行为,尤其是不属于您自己的代码,有哪些道德含义?
我目前正在尝试使用 Ruby 和 Rails,并且我已经阅读了有关元编程的教程和书籍中的一些部分。许多人提到它是 Ruby 的重要组成部分,但他们并没有真正深入细节。就好像元编程是 Ruby 程序员的最后一道防线。来自 .NET 背景,我很难理解为什么它如此有用。
使用元编程有什么好处?
您可以创建比没有它更具表现力的 API(例如 ActiveRecord 使用元编程来定义基于表的列名的访问器方法,因此您可以编写类似person.age
的东西而不是类似的东西person.read_attribute("age")
,其中person
是一个活动记录对象,并且people
表有一个名为age
) 并且您可以使用比其他方式少得多的代码来完成一些事情。
什么是特征类,它与单例有何不同?
术语“eigenclass”和“singleton class”在 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
结尾
使用代码来修改其他代码的行为,尤其是不属于您自己的代码,有哪些道德含义?
没有任何。
元编程有时间和地点。我认为它在 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-ruby和Ruby 元编程在线教程和元编程多少是太多?.
我真的推荐“Metaprogramming Ruby”这本书,因为它不仅教你元编程,还教你 Ruby 是如何工作的。