简单了解Metaprogramming in Ruby

Metaprogramming是ruby的一个特性,可以动态的修改语言结构,比如类结构,模块结构和实例变量信息等等。

甚至可以在运行时往程序中加入并运行新的代码而不需要重启你的程序。

1. 本篇中先简单了解attr_accessor, attr_reader和attr_writer的用法

class Person

  #可带多个参数,用来自动生成参数的getter和setter方法
  attr_accessor :name, :age

  #只生成参数的getter方法
  attr_reader :height

  #只生成参数的setter方法
  attr_writer :height

end

p = Person.new
p.name = "hanks"
p.age = 20
p.height = 180
puts p.name

2. 内部实现原理是什么样的?

在Ruby中,动态代码的实现是通过一系列的”eval”方法实现的,常用的有eval, instance_eval, class_eval, module_eval

四种,在这里我们将使用class_eval(往class中加入可执行代码)。代码如下:

#往Class类中加入代码,Class类是所有类的基类,也就是这一操作
#会影响到所有的类,这里只是举例,要慎用!
class Class
  
  # *号表示参数个数可以是一个包含1个或者是任意多个元素的数组
  def my_attr_accessor(*args)

    #iterator循环,也就是对每一个参数做一些什么样的操作
    args.each do |arg|

      # getter的写法, %Q表示eval中的表达式可以多行
      self.class_eval %Q{

        # #{x}动态根据参数名构造函数名
        def #{arg}
          # @#{x}表示动态根据参数名构造私有变量
          return @#{arg}
        end

      }

      #setter的写法,一行的写法
      self.class_eval("def #{arg}=(val);@#{arg}=val;end")

    end

  end  

end

#用法如下
class Person
  my_attr_accessor :name, :age
end

p = Person.new
p.name = "hanks"
p.age = 20
puts p.name
puts p.age


目前有关四种eval的用法的区别还不是太了解,继续学习啊~~