- 浏览: 1038841 次
- 性别:
- 来自: 成都
-
文章分类
最新评论
-
繁星水:
Useful!!
Object-C之(Null)与(Bool) -
pacer123:
请问注解@ApiModelProperty 在哪个jar包下面 ...
Micro Service工具集之Swagger:可测试的样式化API文档 -
sucheng2016:
这东东真的好用么/
对象转换利器之Dozer -
zzq0324:
http://git.oschina.net/zzq0324/ ...
基于Spring-WS的Restful API的集成测试 -
lrz0534:
你好,我在maven上面下载了swagger-springmv ...
Micro Service工具集之Swagger:可测试的样式化API文档
当前类
不同于JAVA等静态语言,类定义中只能执行定义变量和方法的语句,在Ruby中,类定义的代码和其他的代码是一样的,可以在其中执行任何的Ruby语句。
在Ruby中,不管代码执行到哪个位置,都会有一个当前对象self,相对应的,也总会有一个当前类的存在。当定义一个方法时,该方法就会成为当前类的一个实例方法。跟踪当前类在Ruby中也并不困难,当使用class或module关键字打开一个类的时候,当前类就是被打开的那个类,在类定义时,当前对象self和当前类都是类对象本身,在调用方法时,当前对象self是调用方法的实例对象,当前类是该实例对象的类。
在顶层对象时,当前对象self是Object类的实例对象main。在定义方法时,所有在顶层创建的方法,都会成为Object类的实例方法,但是,该方法被设置成了private访问权限,因此,你无法为该方法显式的指定一个调用者,但是可以在对象内部中调用该方法。
之前讲过,可以使用class关键字打开一个类,但是这必须首先知道类的名字。 Ruby提供了方法Module#class_eval()方法来处理不知道类名,却想打开一个类的情况。
实例变量
Ruby中在变量名前加前缀‘@‘即表示为实例变量,实例变量隶属于定义该变量时的当前对象self,因此类定义时的实例变量属于类,实例方法定义时的实例变量隶属于调用该方法的对象。
在Ruby中,类实例变量只能被类本身访问,类的实例和子类都不能访问。所以千万不要把类实例变量等同于Java世界的静态变量了。
单件方法,类宏
在Ruby中,可以针对某个实例对象添加方法,这样,该扩展就不会对该类的其他实例对象产生影响,这种只针对单个对象生效的方法称之为’单件方法‘(singleton method)。
在Ruby中,可以在类定义中使用一些类方法,这些方法的使用看起来很像关键字,这种方法一般称之为类宏(Class Macro),Module#attr_accessor方法就是一个典型代表,开发者也可以定义自己的类宏。
在Ruby这样的动态语言中,对象的类型只是一组该对象能响应的方法,对象可以使用单件方法继续扩展该对象而不受类型的限制。在本系列第二篇:方法的妙用一文中,描述了Ruby中方法调用的过程,“向左一步进入该对象的类,然后沿着祖先链一直查找方法,找到方法之后,根据自身的绑定执行该方法”。
因此,对象本身只有一组绑定,而方法定义都是在类中。那么上面说到的单件方法和类宏应该在什么地方定义呢? 单件方法肯定不能定义在类中,否则将会影响该类的所有实例对象。类本身也是对象,类的方法不能定义在自身,因为对象的方法必须定义在对象的类中,而类对象的类是Class,如果把类方法定义到Class上,那么所有的类对象都会拥有该方法。这一切迷思的答案都来源于一个Ruby中的高级概念,Eigenclass
Eigenclass
在Ruby中,当调用obj.class向一个对象索要它的类的时候,编译器并没有告诉大家全部的真相,你得到的类并不是你看到的类,你得到的是一个对象特有的隐藏类,这就是该对象的Eigenclass,虽然Object#class方法想把关于Eigenclass的信息隐藏起来,但是,存在即存在,总会被人挖出来的。
Eigenclass是一个类,但是是一个很特殊的类,它只能有一个实例,且不能被继承,但是其自身可以继承其它类。因此,所有的对象都有一个自己的Eigenclass,单件方法就定义在该对象的Eigenclass中,类宏定义在该类对象的Eigenclass中。
既然Eigenclass是一个类,那么其继承体系是怎样的?
为了区分普通类和Eigenclass,Ruby会使用“#"表明该类是一个Eigenclass。从上面的代码的结果可以看出:
* 一个实例对象的Eigenclass的父类是该对象的类
* 一个类对象的Eigenclass的父类是该类对象的父类的EigenClass。
* BasicObject对象的Eigenclass的祖先链最后会回到BasicObject本身。
对象模型的大一统
本系列写到今天,涉及到了无数的对象模型概念,比方说,实例,类,模块,Eigenclass,还有实例方法,实例变量,当前对象self,当前类,单件方法,类宏等等。这些初看起来非常复杂的概念,当深入进去之后,就会发现,复杂性慢慢褪去。一切都变得简单,清晰起来,如果把Eigenclass、类和模块归结为一个东西的话(因为它们本质上的概念差不多,姑且统称为模块),Ruby的对象模型可以总结为一下几条规则:
不同于JAVA等静态语言,类定义中只能执行定义变量和方法的语句,在Ruby中,类定义的代码和其他的代码是一样的,可以在其中执行任何的Ruby语句。
result = class MyClass puts 'Hello' # => Hello self end puts result # => MyClass
在Ruby中,不管代码执行到哪个位置,都会有一个当前对象self,相对应的,也总会有一个当前类的存在。当定义一个方法时,该方法就会成为当前类的一个实例方法。跟踪当前类在Ruby中也并不困难,当使用class或module关键字打开一个类的时候,当前类就是被打开的那个类,在类定义时,当前对象self和当前类都是类对象本身,在调用方法时,当前对象self是调用方法的实例对象,当前类是该实例对象的类。
class MyClass def my_method def inner_method puts "inner method" end end end obj = MyClass.new obj.my_method obj.inner_method # => inner_method
在顶层对象时,当前对象self是Object类的实例对象main。在定义方法时,所有在顶层创建的方法,都会成为Object类的实例方法,但是,该方法被设置成了private访问权限,因此,你无法为该方法显式的指定一个调用者,但是可以在对象内部中调用该方法。
require File.dirname(__FILE__)+ '/my_class' puts self.class # => Object puts self.to_s # => main def my_method puts 'My Method' end Test.new.test # => My Method Object.new.my_method # => private method `my_method' called for #<Object:0x007f8dfa03a3b0> (NoMethodError)
class Test < Object def test my_method end end
之前讲过,可以使用class关键字打开一个类,但是这必须首先知道类的名字。 Ruby提供了方法Module#class_eval()方法来处理不知道类名,却想打开一个类的情况。
def add_method_to(className) className.class_eval do def add_method puts 'Add Method' end end end class MyClass end add_method_to(MyClass) MyClass.new.add_method
实例变量
Ruby中在变量名前加前缀‘@‘即表示为实例变量,实例变量隶属于定义该变量时的当前对象self,因此类定义时的实例变量属于类,实例方法定义时的实例变量隶属于调用该方法的对象。
class MyClass @var =1 def write @var = 2 end def read @var end def self.read @var end end obj= MyClass.new obj.write puts obj.read # => 2 puts MyClass.read # => 1
在Ruby中,类实例变量只能被类本身访问,类的实例和子类都不能访问。所以千万不要把类实例变量等同于Java世界的静态变量了。
单件方法,类宏
在Ruby中,可以针对某个实例对象添加方法,这样,该扩展就不会对该类的其他实例对象产生影响,这种只针对单个对象生效的方法称之为’单件方法‘(singleton method)。
str = "he" def str.double self * 2 end puts str.double # => hehe another_str="another" puts another_str.double # => undefined method `double' for "another":String
在Ruby中,可以在类定义中使用一些类方法,这些方法的使用看起来很像关键字,这种方法一般称之为类宏(Class Macro),Module#attr_accessor方法就是一个典型代表,开发者也可以定义自己的类宏。
class Matcher def match puts 'match' end def match_safely puts 'match safely' end def self.deprecated(old_method, new_method) define_method(old_method) do |*args, &block| warn "Warnning: #{old_method} is depracated, please use #{new_method} instead!" send(new_method, *args, &block) end end deprecated :match, :match_safely end Matcher.new.match # => Warnning: match is deprecated, please use match_safely instead! # => match safely
在Ruby这样的动态语言中,对象的类型只是一组该对象能响应的方法,对象可以使用单件方法继续扩展该对象而不受类型的限制。在本系列第二篇:方法的妙用一文中,描述了Ruby中方法调用的过程,“向左一步进入该对象的类,然后沿着祖先链一直查找方法,找到方法之后,根据自身的绑定执行该方法”。

因此,对象本身只有一组绑定,而方法定义都是在类中。那么上面说到的单件方法和类宏应该在什么地方定义呢? 单件方法肯定不能定义在类中,否则将会影响该类的所有实例对象。类本身也是对象,类的方法不能定义在自身,因为对象的方法必须定义在对象的类中,而类对象的类是Class,如果把类方法定义到Class上,那么所有的类对象都会拥有该方法。这一切迷思的答案都来源于一个Ruby中的高级概念,Eigenclass
Eigenclass
在Ruby中,当调用obj.class向一个对象索要它的类的时候,编译器并没有告诉大家全部的真相,你得到的类并不是你看到的类,你得到的是一个对象特有的隐藏类,这就是该对象的Eigenclass,虽然Object#class方法想把关于Eigenclass的信息隐藏起来,但是,存在即存在,总会被人挖出来的。
obj = Object.new eigenclass = class << obj self end puts eigenclass.class # => Class
Eigenclass是一个类,但是是一个很特殊的类,它只能有一个实例,且不能被继承,但是其自身可以继承其它类。因此,所有的对象都有一个自己的Eigenclass,单件方法就定义在该对象的Eigenclass中,类宏定义在该类对象的Eigenclass中。
既然Eigenclass是一个类,那么其继承体系是怎样的?
module A def test puts 'test' end end class GrandFather def self.eigenclass class << self self end end end class Father < GrandFather include A end obj = Father.new obj_eigenclass = class << obj self end puts obj_eigenclass # => #<Class:#<Father:0x007f8fe5037a38>> puts obj_eigenclass.superclass # => Father puts obj_eigenclass.method_defined? :test # => True puts GrandFather.eigenclass # =>#<Class:GrandFather> puts GrandFather.eigenclass.superclass # =>#<Class:Object> puts GrandFather.eigenclass.method_defined? :test # => false puts Father.eigenclass # =>#<Class:Father> puts Father.eigenclass.superclass # =>#<Class:GrandFather> puts Father.eigenclass.method_defined? :test # => false
class BasicObject def self.eigen class <<self self end end end puts BasicObject.eigen # => #<Class:BasicObject> puts BasicObject.eigen.ancestors.to_s # => [Class, Module, Object, Kernel, BasicObject]
为了区分普通类和Eigenclass,Ruby会使用“#"表明该类是一个Eigenclass。从上面的代码的结果可以看出:
* 一个实例对象的Eigenclass的父类是该对象的类
* 一个类对象的Eigenclass的父类是该类对象的父类的EigenClass。
* BasicObject对象的Eigenclass的祖先链最后会回到BasicObject本身。

对象模型的大一统
本系列写到今天,涉及到了无数的对象模型概念,比方说,实例,类,模块,Eigenclass,还有实例方法,实例变量,当前对象self,当前类,单件方法,类宏等等。这些初看起来非常复杂的概念,当深入进去之后,就会发现,复杂性慢慢褪去。一切都变得简单,清晰起来,如果把Eigenclass、类和模块归结为一个东西的话(因为它们本质上的概念差不多,姑且统称为模块),Ruby的对象模型可以总结为一下几条规则:
- 关于对象,只有2种对象,要么是实例对象,要么是模块对象,用于存放实例变量的绑定。
- 关于模块,它可以是Eigenclass,类,或模块。用于存放方法和一些类实例变量。
- 关于方法,方法必须存在于一种模块中。
- 每个对象(包括模块对象)都有自己的Eigenclass,用于保存当前对象的单件方法(类对象的就是类宏)。
- 除了BasicObjec类无超类以外,所有的模块对象都有且只有一个父类,即从任何模块对象只有一条向上直到BasicObject的祖先链。
- 一个实例对象的Eigenclass的父类是该实例对象的类,一个模块对象的eigenclass的超类是该模块对象的超类的eigenclass。
- 在类对象中插入一个模块时,该模块会出现在该类的祖先链的正上方。
- 调用方法时,Ruby总是先向“右”迈一步进入接收者真正的类中,然后向上进入祖先链。
发表评论
-
Ruby IO之ARGF,ARGV
2013-11-23 15:44 3558在使用ruby脚本时, 经常需要用到在参数中给出文件名,然后再 ... -
Luhn算法的Ruby实现
2013-11-22 20:18 1262什么是Luhn算法? Wiki上得标准定义:http://en ... -
使用Sinatra创建Soap Web Service
2013-11-21 17:58 1542简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML ... -
Ruby之代码块的迷思
2013-05-05 18:51 6887块的定义、调用与运行 在Ruby中,定义一个代码块的方式有2种 ... -
Ruby之方法的妙用
2013-05-01 20:18 3922方法的查找与执行 Ruby中对象的方法都定义在类中,当对象想要 ... -
Ruby之类的真相
2013-04-29 18:12 2728打开类和猴子补丁 在Ruby中,类定义的方法和其他的语句没有任 ... -
Sinatra 101(3)--自动化测试
2013-04-24 18:44 1952首先,安装rspec,非常简单 gem install rsp ... -
Sinatra 101 (2)–快速构建一个Note系统
2013-04-22 15:51 1697Views Sinatra中,默认所有的页面都放在views目 ... -
Sinatra 101(1)
2013-04-19 16:09 2220介绍 Sinatra是由 Blake Mizerany在200 ... -
HAML学习笔记
2013-01-20 22:51 4456一个技术能够风靡,一定是有它的原因的,在熟悉之前,我们没有资格 ... -
Rails的MVC和路由策略
2012-07-15 20:53 1584MVC In Rails 在rails中,发送一个请求(/u ... -
End To End RoR Demo
2012-07-13 22:02 11331、生成项目架构 rails ne ... -
Ruby&CouchDB之Hello World
2012-07-09 22:20 1089require 'net/http' module Co ... -
《Rails Step by Step》之Rails的目录结构
2012-07-09 21:41 1273刚开始学Rails,因为其“约定大于配置”的特性,让开发 ... -
《松本行弘的程序世界》之让程序飞(Ruby版)
2012-07-01 00:15 1714为什么要做性能优化? “过早优化是万恶之源”,作为 ... -
Ruby之猴子补丁
2012-06-25 21:58 3937何谓猴子补丁(Monkey Patch)?在动态语言中,不修改 ... -
Cucumber 入门学习
2012-04-11 21:38 209301、Cucumber是什么 Cucumber是一个在 ... -
关于DSL(Domain Specification Language)的由来
2012-04-10 22:42 1433最近在学习Ruby的时候,看到Martin Fow ... -
GitHub的Ruby代码规范
2012-04-07 11:33 5049最近开始接触Ruby和Rails的开发,个人是一个疯狂迷 ...
相关推荐
《Ruby面向对象设计实践》是一本关于如何在Ruby语言中实现面向对象编程(Object-Oriented Programming, OOP)的经典著作。该书首次出版于2013年,作者是Sandi Metz,一位著名的软件工程师和培训师,在软件开发领域...
Ruby是一种动态、面向对象的编程语言,而Her是Ruby社区中的一款ORM(对象关系映射)库,专门用于处理RESTful API。ORM允许开发者用面向对象的方式来操作数据库,而无需直接编写SQL语句,简化了数据操作的过程。Her库...
**Ruby**是一种完全面向对象的编程语言,这意味着在Ruby中,一切事物都是对象。无论是字符串、数字、布尔值甚至是`true`和`false`这样的基本数据类型,都是作为对象处理的。类本身也是对象,是`Class`类的一个实例。...
《Ruby面向对象设计》一书由Pearson Education出版社发行,该出版社是全球教育行业的领导者之一,提供各种教育和学习资源。书籍的版权声明中提及了版权保护、商标声明、使用许可等方面的内容。这显示了出版社对于...
在Ruby编程语言中,"面向对象的枚举"是一个重要的概念,它结合了面向对象编程的灵活性和枚举类型的效率。Ruby的枚举通常指的是枚举类(Enum Class),这是一种自定义枚举类型的方法,允许我们创建具有特定行为的枚举...
面向对象的脚本语言Ruby
总的来说,Ruby-Reform是Ruby开发中的一个强大工具,能够极大地改善你的表单处理体验。它提供了更清晰的代码结构,易于测试的表单逻辑,以及对嵌套数据的优雅处理。如果你在Ruby项目中经常处理复杂的表单,那么...
MongoMapper是Ruby社区中用于MongoDB数据库的一种对象关系映射(ORM)框架,它为开发者提供了与MongoDB交互的简洁而强大的接口。MongoDB是一种非关系型数据库(NoSQL),以其灵活性、高可用性和高性能而受到青睐。...
根据给定文件中的标题“ruby多模型绑定”及其描述、标签和部分内容,我们可以总结出以下相关的知识点: ## Ruby on Rails 多模型绑定 ### 1. 多模型绑定概念介绍 在 Ruby on Rails(以下简称 Rails)框架中,多...
它旨在帮助开发者以简洁、高效的方式将Ruby对象转换为符合JSON:API规范的JSON格式,极大地提高了开发效率和应用程序的性能。 JSON:API是一个广泛接受的标准,它定义了如何在客户端和服务器之间交换数据,包括资源的...
Ruby Wisper库是一个轻量级的解决方案,它为Ruby对象引入了发布-订阅(Publish-Subscribe,简称Pub/Sub)模式。这种模式允许对象之间通过事件进行通信,而不是直接调用方法,从而增强了代码的解耦性和可扩展性。在...
Ruby-Kashmir是一个专门为Ruby开发者设计的Domain Specific Language(DSL),它的主要目标是简化对象的序列化和缓存过程。通过这个库,开发者可以方便地管理和存储他们的数据,提高应用程序的性能,尤其是在处理...
Ruby编程语言是由Yukihiro Matsumoto(又称为Matz)创建的一种面向对象的语言,它以其简洁、优雅的语法和强大的功能而闻名。《Ruby Programming—向Ruby之父学程序设计(第2版)》这本书旨在帮助初学者,甚至是完全...
《Ruby Programming:向Ruby之父学程序设计(第2版)》是为了让完全没有程序设计经验的读者也能灵活地使用Ruby,因此书中详细地说明了各种知识。从程序所需要的变量、常数、方法、类、控制结构等语法的说明,到类的主要...
Ruby基础语法 ...Ruby面向对象编程 Ruby模块与包 Ruby错误处理 Ruby文件与I/O操作 Ruby正则表达式 Ruby网络编程 Ruby数据库交互 Ruby测试框架 RubyWeb框架Rails入门 Ruby高级特性 Ruby性能优化与最佳实践
第一部分的内容包括对Ruby语言一个概要介绍和对Ruby对象模型的讲解。从我个人阅读的感觉来看,第一章对于Ruby语言的介绍是一个非常好的起步教程,把Ruby语言中一些核心点都指了出来。比起我读到过一些Ruby语言教程,...
Ruby-Ancestry是一个非常有用的库,它允许开发者在ActiveRecord模型中构建和管理层次结构,形成树状结构。这个库特别适用于那些需要处理有层级关系数据的场景,比如分类、菜单系统、组织架构等。Ancestry通过提供一...
《Practical Object-Oriented Design in Ruby 新版 实战ruby面向对象设计》是一本非常受欢迎的编程书籍,它不仅是学习Ruby语言的重要参考资料,也是深入理解面向对象编程(OOP)技术不可或缺的宝贵资料。这本书由于...