转帖:
http://hi.baidu.com/mepm/blog/item/edb5e1500c75975c1038c2f6.html
元编程并不是一个很新的概念,通常元编程被认为是通过程序来生成程序,如果从这种意义上来考虑,那么lex和yacc以及JavaCC应该都可以算是具有 了元编程的概念,在Java中,元编程得到了广泛的应用。但在Ruby中,元编程的使用变得相当的简单和容易实现,使用Ruby语言本身来产生Ruby代 码,不需要借助外部的工具,著名的RoR框架就是建立的Ruby元编程的基础上的。可能你你对元编程还没什么概念,但是Ruby已经内建了元编程这种机 制,所以很有可能,你在不知不觉中就已经使用了Ruby元编程技术为你带来的方便之处。如下面这段代码:class Person
attr_reader :name
end
你肯定知道 :name 是和 @name 相关联的,但是你不一定清楚它到底是怎么实现的,其实attr_reader方法的实现就是采用了元编程技术,如下面的这段代码:
ruby 代码
- class Module
- def attr_reader(*syms)
- syms.each do |sym|
- class_eval %{def
- @
- end
- end
- end
- end
看了这段代码,你应该大概了解元编程的机制了吧,如果你现在还不了解,那么我建议你先认真的学习一下Ruby的反射机制,然后再接下去看这篇帖子,因为下面介绍的内容并不是一杯婴儿奶粉。
在Ruby On Rails中,有一个OR映射层,就是动态的从一张关系表映射到一个对象,这主要由ActiveRecord类来实现。在OR映射模型中,将关系数据库中的关系表表映射到对象模型时,将关系表的表名映射到类名,表中的每一个元组映射到对应于这个类的一个对象,元组的一个字段对应于对象的一个属性。
假如我们有一个保存职员基本信息的文件,文件的格式是这样的:第一行是文件内容的每个字段的名称,从第二行开始,则是每个职员的基本信息。现在我们有一个文件名为“employee.txt”的文件,其内容如下所示:
name,age,gender
"John", 23, "male"
"Linclon", 25, "male"
假设我们就 要从这个文本文件中读取数据,并进行一定的处理。如果是使用C++编程,你首先一定会想到应该定义一个Employee类,然后这个类中有name, age, gender这些成员变量。但是是采用这种方法的话,可以发现,如果想在职员信息中加入一个字段,比如部门(department),就不得不修改 Employee类的代码,在Employee类中增加一个“department”成员变量,所以我们的代码是高度依赖于文件的具体格式,这当然不是一 个好的现象。我们希望有一种更简单和优雅的方案,还有,Ruby动态性提高给我们一个解决方案,但是,我们应该从和下手呢,这就需要Ruby的元编程能 力。
首先,我们想应该有一个职员类,在Rails中,每个关系表的名称会成为类的名称,在这里,采用类似的方法,将文本文件的名称作为类的名称,在Ruby中,类名同时也是一个常量名,所以第一个字母必须为大写,我们使用如下的代码来生成类名。
class_name = File.basename(file_name, ".txt").capitalize
# "employee.txt" => "Employee"
klass = Object.const_set(class_name, Class.new)
Class.new生成一个新的类,这个类的名称是匿名的,所以采用const_set操作来绑定一个类名,变量klass是新类型的引用。
生成了这个类以后,需要想这个类添加姓名,年龄和性别这些属性,这些属性的名称是在文本文件的的第一行中给出的。
data = File.new(file_name)
header = data.gets.chomp
data.close
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)
end
end
#...
end
现在,有了一系列的访问子(可读和可写),通过instance_variable_set方法,又给每个属性做了初始化。
变量names是在块外部定义的,由于块的闭合性,所以变量names在块中也是有效的。当然,为了程序的演示,又定义的了一个to_s方法,代码如下所示:
define_method(:to_s) do
str = "<#{self.class}: "
names.each {|name| str << "#{name}=#{self.send(name)} "}
str + ">"
end
alias_method :inspect, :to_s
完成了这些以后,对于类的构造已经基本结束了,现在就需要真正的从文本文件中读取数据了。从文本文件读数据应该是一个类方法,而不是一个实例的方法,其实现代码如下:
def klass.read
array = []
data = File.new(self.to_s.downcase + ".txt")
data.gets #throw away header
data.each do |line|
line.chomp!
values = eval("[#{line}]")
array << self.new(*values)
end
data.close
return array
end
在这个方法中,使用字的类名来匹配相关的文件,比如将Employee类映射到“employee。txt”。
然后,从文件中读取职员信息,由于第一行是字段定义,所以要舍弃第一行数据。从第二行开始读取数据,每读取一行数据,则构造一个Employee实例。通过上面这个简单的例子,我们可以看出元编程的功能是相当之强大的,使用元编程技术,可以构造相当简单,优雅的解决方案。
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
# "employee.txt" => "Employee"
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)
end
end
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 #throw away header
data.each do |line|
line.chomp!
values = eval("[#{line}]")
array << self.new(*values)
end
data.close
return array
end
return klass
end
end
DataRecord.make("employee.txt")
list = Employee.read
puts list
<ouput></ouput>
非常受用。目前正在解决一个类似的问题。需要将一个返回的字符串解释成一个类。
分享到:
相关推荐
Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门与实践 Ruby编程语言入门...
### Ruby元编程核心知识点概述 #### 一、元编程概念及意义 元编程是一种编程技术,它允许程序在运行时修改或生成其他程序的行为。在《Ruby元编程》这本书中,作者通过一系列案例来深入浅出地介绍了Ruby语言中独特...
内容概要:本文详细介绍了Ruby编程语言的安装、基础语法、面向对象编程、常用模块和库、异常处理等内容。首先介绍了如何在不同操作系统上安装Ruby,接着讲述了变量、数据类型、控制结构、方法定义等基础语法,随后...
内容概要:本文全面介绍了Ruby编程语言的基础知识和高级特性,从安装Ruby到基本语法规则,再到类与对象的概念。同时深入讲解了模块与混入、块与Proc、异常处理、元编程等高级特性,并通过创建命令行工具和Web应用的...
Ruby on Rails(简称Rails)是基于Ruby编程语言的开源框架,以其“DRY(Don't Repeat Yourself)”和“Convention Over Configuration”原则著称,极大地提高了开发效率和代码可读性。 本书首先会介绍Ruby语言的...
Ruby on Rails,简称Rails,是一种基于Ruby编程语言的开源Web应用程序框架,以其“Convention over Configuration”(约定优于配置)和“Don't Repeat Yourself”(DRY,不要重复自己)的原则著称。Rails使得开发Web...
Ruby是一种简洁、灵活且具有强大功能的面向对象编程语言。它在编程界备受瞩目,并且在各种应用程序开发中广泛使用。本教程将带领你从零开始学习...无需担心,即使你是一个完全的编程初学者,也能够轻松入门Ruby编程。
### 第二章:Ruby编程环境 #### §2.1 Ruby的安装 安装Ruby的过程因操作系统而异: - **Windows**:通过下载RubyInstaller,按照向导进行安装。 - **Linux**:通常可以通过包管理器(如apt-get或yum)轻松安装。 #...
### Ruby编程语言简介 #### 一、Ruby编程语言概述 Ruby是一种动态的、面向对象的、通用型的编程语言,自1995年由日本程序员松本行弘(Yukihiro Matsumoto)创建以来,便以其简洁优雅的语法、高度可读性和易于学习...
标题中的“Ruby相关入门教程网址”表明这是一份关于学习Ruby编程语言的资源,而描述中的“博文链接:https://musicbox95351.iteye.com/blog/1797113”提示我们可以从这个链接找到更多关于Ruby的入门教程。...
适合有点编程经验,先看ruby双飞燕,再看ruby元编程。 pdf,有目录,英文,这种资料尽量看英文的。 ruby双飞燕:The Ruby Programming Language ruby元编程:Pragmatic.Metaprogramming 助您学习又称
内容概要:本篇《Ruby入门教程》引导初学者通过简易的例子逐步理解Ruby的基本语法概念及其特点,诸如IRB的应用、方法定义与使用以及类的概念与面向对象的设计等关键内容,最终演示了一段完整的程序案例以深化理解和...
- 《Ruby编程语言》是一本权威的Ruby学习指南。 - **在线教程** - 如RubyMonk、Codecademy等网站提供交互式的Ruby学习课程。 通过上述介绍,我们可以看到Ruby不仅具备简洁优雅的语言特性,还有着丰富的生态系统和...
它支持面向对象编程(OOP)、函数式编程(FP),并具有强大的元编程能力,这使得Ruby成为构建复杂应用程序的理想选择。此外,Ruby拥有活跃的社区和丰富的生态系统,包括Rails框架,后者极大地简化了Web应用的开发...
- Ruby的元编程能力强大,可以在运行时修改类和对象的行为。 - eval()函数可以执行字符串形式的代码,define_method动态定义方法。 7. **Rails框架**: - Ruby on Rails是Ruby最著名的Web开发框架,它遵循MVC...
松本行弘原著,Ruby编程入门非常好的书籍。共两个文件
Ruby是一种面向对象的、动态类型的编程语言,由日本的松本行弘(Yukihiro Matsumoto)于1995年设计并开发。它强调代码的简洁性和可读性,致力于提供一种更自然的编程方式,让程序员可以更加专注于解决问题而不是语言...
《The Book of Ruby》不仅是一本优秀的Ruby编程入门书籍,更是一部全面涵盖Ruby编程语言各个方面的重要参考文献。无论你是刚刚接触编程的新手,还是拥有一定经验但想进一步提升自己的开发者,都能从中获得有价值的...