元编程入门
define_method/class_eval/instance_eval、method_missing、反射
元编程入门
Ruby 在运行时可以定义方法、创建类、拦截方法调用——这就是元编程,Rails 的魔力来源。
学完本章你将: 掌握 define_method、class_eval、method_missing、反射。
define_method —— 运行时定义方法
ruby
class User
ATTRIBUTES = [:name, :email, :age]
ATTRIBUTES.each do |attr|
define_method(attr) do
instance_variable_get("@#{attr}")
end
define_method("#{attr}=") do |value|
instance_variable_set("@#{attr}", value)
end
end
end
# 等价于手写了 6 个方法——attr_accessor 底层就是这样实现的
method_missing —— 拦截未知方法
ruby
class ConfigProxy
def initialize
@config = {}
end
def method_missing(method, *args, &block)
if method.to_s.end_with?("=")
@config[method.to_s.chomp("=").to_sym] = args.first
else
@config[method]
end
end
def respond_to_missing?(method, include_private = false)
true
end
end
config = ConfigProxy.new
config.host = "localhost" # 实际调用 method_missing
config.port = 8080
puts config.host # "localhost"
反射
ruby
"hello".methods # 所有方法
"hello".public_methods # 公开方法
String.instance_methods # String 的实例方法
User.private_methods # 私有类方法
user.instance_variables # [@name, @email]
user.instance_variable_get(:@name)