Ruby 中的类和对象
2016-07-27 19:55
441 查看
近在ruby-china中闲逛,无意中发现了一位网友提出的问题,这个问题相当有意思,并且促使我写下了这篇博客。
原问题是这样描述的:
简单的几行代码,我竟一时答不上来,不禁汗颜!接触ruby也有一年多了,自认为很熟悉这门语言,但这个问题却把自己打回原型。不过我相信,至少有90%的ruby程序员会被这个问题难住,所以我觉得很有必要研究一下这个问题,让自己,也让别人搞明白,为什么会这样。
首先,我想每个人心中都会有这样一个疑问:
我们暂时放下这个问题,去分析一下
让我们先写一个普通类,看它是否和
我们写了一个
正如我们预料的一样,
ruby对象模型是理解ruby语言的关键
ruby中,可以使用
从这里可以看出ruby中一个非常重要的概念:类自身也是对象。
既然类自身也是对象,那么我们也可以把
What happened? 和ruby对象模型中描述的一样,
在这里,
对于
根据ruby的方法查找方式:沿着祖先链查找。
我们试着找出
我们终于找到了do_it方法,一切都真相大白!!!而这一切都如ruby对象模型中描述的一模一样。
简单的一个问题,却折射出学习ruby三个最重要的知识点:
ruby中,一切皆对象
理解ruby对象模型
了解ruby查找方法的方式
原问题是这样描述的:
class Object def do_it puts "do it" end end Object.do_it #这个class method 怎么来的? Object.new.do_it
简单的几行代码,我竟一时答不上来,不禁汗颜!接触ruby也有一年多了,自认为很熟悉这门语言,但这个问题却把自己打回原型。不过我相信,至少有90%的ruby程序员会被这个问题难住,所以我觉得很有必要研究一下这个问题,让自己,也让别人搞明白,为什么会这样。
首先,我想每个人心中都会有这样一个疑问:
do_it很明显是
Object对象的实例方法,而
Object是一个类,类怎么可以直接调用其实例方法呢?
我们暂时放下这个问题,去分析一下
Object这个类,它到底有什么特别之处。
让我们先写一个普通类,看它是否和
Object类有相似的特性。
irb(main):001:0> class Test irb(main):002:1> def do_it irb(main):003:2> puts "do it" irb(main):004:2> end irb(main):005:1> end
我们写了一个
Test类,它也有一个
do_it方法,我们可以让
Test类来调用
do_it,看会发生什么:
irb(main):006:0> Test.do_it NoMethodError: undefined method `do_it' for Test:Class
正如我们预料的一样,
Test并不能调用
do_it这个实例方法,那
Object为什么可以办到呢?
irb(main):007:0> Test.ancestors => [Test, Object, Kernel, BasicObject] irb(main):010:0> Test.superclass => Object
ancestors方法可以查看当前类的祖先链,我们可以清楚的看到:
Object类是
Test类的超类(正确来说,所有类最终都继承于
Object)。
ruby对象模型是理解ruby语言的关键
ruby中,可以使用
class方法查看对象所属的类。
irb(main):011:0> a = Test.new => #<Test:0x007ffee21212c0> irb(main):012:0> a.class => Test irb(main):013:0> Test.class => Class
从这里可以看出ruby中一个非常重要的概念:类自身也是对象。
既然类自身也是对象,那么我们也可以把
Object类当作对象。
irb(main):014:0> Object.class => Class irb(main):013:0> Test.class => Class
What happened? 和ruby对象模型中描述的一样,
Object类和
Test类都属于
Class类。然后我们再回到之前的代码:
Object.do_it
在这里,
Object是类还是对象呢?
irb(main):024:0> Object.instance_methods => [:do_it, :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
instance_methods方法可以打印出当前类所拥有的所有实例方法,很明显,
do_it是
Obje1ct类的实例方法。
对于
Object.do_it,如果把
Object当作类来看,很明显类无法直接调用实例方法,但是如果把
Object当作对象来看,情况就不一样了。
根据ruby的方法查找方式:沿着祖先链查找。
我们试着找出
Object是如何找到
do_it的方法的。
irb(main):026:0> Object.class => Class //Object所属的类是Class,Class中没有定义do_it,然后查找超类 irb(main):027:0> Class.superclass => Module //Module中也没有定义do_it,继续查找超类 irb(main):028:0> Module.superclass => Object //My god! Module的超类竟然是Object,而Object中确实定义了do_it方法
我们终于找到了do_it方法,一切都真相大白!!!而这一切都如ruby对象模型中描述的一模一样。
简单的一个问题,却折射出学习ruby三个最重要的知识点:
ruby中,一切皆对象
理解ruby对象模型
了解ruby查找方法的方式
相关文章推荐
- Ruby 中一些好用的方法(注意reduce方法)
- ruby中星号(*)的作用
- gmt_offset变量是干什么的
- CocoaPod的安装与问题处理
- mac下升级ruby环境版本
- 如何快速正确的安装 Ruby, Rails 运行环境-b
- ruby自动化之selenium webGUI
- cocoaPods安装遇到的问题以及解决方案
- ruby开发环境配置
- MAC机中安装ruby环境--转载
- Ruby(1):入门
- cocoapods的最新安装 遇到的坑 Error installing pods:activesupport requires Ruby version >= 2.2.2
- Ruby中 respond_to? 和 send 的用法 .
- 记录ruby的一些函数方法使用点点滴滴
- [Ruby]Rails的MVC部分理解
- 安装Ruby环境和下载和安装CocoaPods
- Ruby中使用each和collect进行迭代的用法
- ruby解析json、xml
- Mac上更新Ruby
- ruby on rails 常用的日期取值