一个简单的ruby Metaprogram的例子

阅读更多
比如下面一个文件 people.txt

引用
name,age,weight,height
"Smith, John", 35, 175, "5'10"
"Ford, Anne", 49, 142, "5'4"
"Taylor, Burt", 55, 173, "5'10"
"Zubrin, Candace", 23, 133, "5'6"


我们的目标是什么呢?我们的目标就是实现类似于Rails中的Builder模块所做的事情,假设我们第二行数据 对象为a,那么我们可以通过a.name,a.age等等来得到他所对应的值:

class DataRecord    
      def self.make(file_name)
        data = File.new(file_name)
        header = data.gets.chomp
        data.close
#首先得到文件名,然后根据文件名动态的创建此文件对应的类
        class_name = File.basename(file_name,".txt").capitalize  
        klass = Object.const_set(class_name,Class.new)
        names = header.split(",")
#设置实例变量,并且将实例变量赋值
        klass.class_eval do
          attr_accessor *names
          define_method(:initialize) do |*values| 
            names.each_with_index do |name,i| 
              instance_variable_set("@"+name, values[i])
            end
          end   
#当put时能打印出显示更好的结果
          define_method(:to_s) do
            str = "<#{self.class}:"
            names.each {|name| str << " #{name}=#{self.send(name)}" }
            str + ">"
          end
          alias_method :inspect, :to_s
        end   
#读取数据然后将每一行数据都放进一个数组
        def klass.read
          array = []
          data = File.new(self.to_s.downcase+".txt")
          data.gets
          data.each do |line| 
            line.chomp!   
            values = eval("[#{line}]")
            array << self.new(*values)
          end
          data.close
          array
        end  
        klass
      end  
end

DataRecord.make("people.txt")
list = People.read   

p list[1].name 
p list[1].age  


你可能感兴趣的:(Ruby,Rails)