Ruby类和模块的关系

oracle 11.2.0.3.0 client下载,oracle64位客户端 Instant Client oracle64位 客户端安装程序,Instant Client v11.2.0.3.0(64-bit)可以用,bo客户端需要配这个的,所以装了一个,64位操作系统中、不安装Oracle-32bit客户端,方便使用PLSQL Developer(不支持64bit位Oracle客户端)安装教程安装配置instantclient下载后,解压到D:\Oracle\instantclient_11_2(特... 阅读详情

       学习ruby入门的时候,很容易被其类和模块的小trick给迷惑住了,这里为了整理自己的理解,就写出来看看吧。

1.ruby一切皆对象

       ruby是彻底地面向对象,你见到的一切构件都是对象。数字是对象,字符串是对象,类也是对象,模块也是对象,甚至类的类(Class)也是对象......

irb(main):001:0> 1.is_a? Object
=> true
irb(main):002:0> Object.is_a? Object
=> true
irb(main):003:0> Class.is_a? Object
=> true
irb(main):007:0> class Test
irb(main):008:1> end
=> nil
irb(main):009:0> Test.is_a? Object
=> true
       其实在这里,像我这样从传统面向对象语言过来的初学者往往会提出疑问:在Java中,我们总可以明显地看出是那个对象在调用方法,但当我进入irb时,并没有创建任何对象,怎么可以调用puts等等方法?这里先不讨论puts方法来源于哪儿,但是当开始执行第一行ruby代码之前,实际上就存在一个对象了。这个对象叫main,是Object的对象。
irb(main):015:0> self
=> main
irb(main):016:0> self.class
=> Object
      此时所处的环境被称为Top Level Context(顶级上下文)。是ruby调用栈的顶端,通常(不在TLC时并非main在充当当前对象)你调用puts等方法时就是这个main对象在充当调用者(接收者)。
2.ruby的类和模块

     ruby的类和模块可以统一看成是对象的分类,ruby中每个对象都有一个分类:

irb(main):017:0> Object.class
=> Class
irb(main):018:0> t=Test.new
=> #<Test:0x1a5aa48>
irb(main):019:0> t.class
=> Test
irb(main):020:0> Kernel.class
=> Module
irb(main):023:0> Module.class
=> Class
irb(main):024:0> Class.class
=> Class

     可以看到,对象的分类是其普通类,类的分类是Class,Kernel模块的分类是Module,Class的分类也是Class,Module的分类也是类。
     甚至于,在ruby中,我们可以认为只有一种分类,那就是模块Module,因为Class是从Module继承而来。

irb(main):011:0> Class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
     除了很少的几个区别,几乎可以将类和模块一视同仁,类只不过是增强后的模块。那么,ruby中其他普通类和Class/Module有什么关系呢?答案是,其他类(模块)不过是Class(Module)的实例而已

irb(main):028:0> Test.instance_of? Class
=> true
irb(main):013:0> Kernel.instance_of? Module
=> true
     根据这个原理,就可以像下面这样定义新类:
irb(main):029:0> MyClass=Class.new do
irb(main):030:1* def say
irb(main):031:2> puts "I am MyClass"
irb(main):032:2> end
irb(main):033:1> end
=> MyClass
irb(main):034:0> m=MyClass.new
=> #<MyClass:0x1a4f798>
irb(main):035:0> m.say
I am MyClass
=> nil
       使用Class.new操作就新建了一个类,把这个类赋值给MyClass,这个新类就定义出来了,可以像使用其他类一样使用。这段代码除了证明普通类不过是Class的实例外,还说明了另一个问题:类名不过是一个常量而已。我们可以查看当前常量列表来验证:

irb(main):038:0> Object.constants.grep /MyClass/
=> [:MyClass]

       

3.ruby的方法查找

      当在ruby程序中调用一个方法时,ruby解释器以方法的接收者或者self为起点,沿着该对象的祖先链往上查找方法,直到找到这个方法或者抛出异常。

       以在TLC中调用puts方法为例,此时puts方法的接收者隐式由self充当,而此时的self是Object类的对象main,那么查看Object类的方法:

irb(main):041:0> Object.methods.grep /puts/
=> []

           在Object中显然并不存在puts方法,那么查看Object的祖先链:

irb(main):042:0> Object.ancestors
=> [Object, Kernel, BasicObject]
       沿着祖先链,我们查看Kernel的方法:

irb(main):043:0> Kernel.methods.grep /puts/
=> [:puts]
       显然puts方法位于Kernel中。从前面知道,Kernel是一个模块,它被混入(Mixin)类中,通常当模块include混入时,模块的方法就成为类的实例方法,由于Kernel模块混入了Object类中,所以在ruby代码的任何地方都可以调用puts方法,因为ruby的几乎全部的类都继承自Object。

       PS.关于private方法:

       ruby中的private方法有时让人很懊恼。但实际上需要记住的只有一点:private方法只能在隐含的接收者self上被调用,但private方法调用的查找规则和其他方法是一样的。所以,即便是TLC中main对象拥有puts方法,但却不能这样调用:

irb(main):046:0> self.puts
NoMethodError: private method `puts' called for main:Object
        from (irb):46
        from C:/RailsInstaller/Ruby1.9.3/bin/irb:12:in `<main>'
        另外,不要和Java等语言中的private混淆,ruby的private方法时可以在子类中调用的:

irb(main):052:0> class Dad
irb(main):053:1> private
irb(main):054:1> def say
irb(main):055:2> puts "Dad says private"
irb(main):056:2> end
irb(main):057:1> end
=> nil
irb(main):058:0> class Son <Dad
irb(main):059:1> def talk
irb(main):060:2> say
irb(main):061:2> puts "son talk"
irb(main):062:2> end
irb(main):063:1> end
=> nil
irb(main):064:0> s=Son.new
=> #<Son:0x1c90cb0>
irb(main):065:0> s.talk
Dad says private
son talk
          最后,补充说一下几个常用方法的调用:

irb(main):067:0> Object.private_methods.grep /method/
=> [:define_method, :method_missing,.........]
          Objcet的method_missing和define_method都是其私有方法,为什么在方法内部调用method_missing正确,而调用define_method就会报错,必须在类上下文充当self时才能调用define_method?

Object#method_missing方法是Object的一个private方法,不能显示地使用接收者调用,但所有对象都可以隐式调用该方法。

而define_method实际上是Module#define_method方法,该方法是Module的private实例方法,而Class又继承了Module类,所以它变成了Class的实例方法,由于所有的普通类都是Class的实例,所以define_method就成为了所有普通类的类方法,所以在类上下文中能够使用define_method此时self由类充当,而不能在某个具体对象充当self时调用该方法。








Ruby模块关系 总结起来,模块Ruby中重要的代码组织重用机制。用于定义对象的结构行为,可以实例化为对象,并支持继承关系模块用于组织重用代码片段,可以被包含在中,并提供可复用的功能。最后,可以被实例化继承,而模块只能被包含在其他中。在Ruby编程语言中,模块是两个核心概念,它们在代码组织代码重用方面起着重要的作用。在实际的开发中,常用于定义具有相似特征行为的对象,而模块常用于提供可复用的代码片段功能。通过将模块包含到中,我们可以实现代码的重用组合,从而提高代码的可维护性可扩展性。 阅读详情

相关推荐

用VirtuosoAbstract完成gds2lef

需要用到的工具有virtuosoabstract。 数模混合的项目通常需要模拟完成模块设计,把接去数字的pin打上label(text),数字的floorplan才能正式开始。 如果只需要简单的数字PR boundarypin点位置,那么只使用virtuoso就够了,还想把模拟版图都转成lef就要用到abstract工具。 1.PR boundary+pin 1)在virtuoso中打开layout a) Gui操作: Create->P&R Objects->

m0_61544122的博客 8604

Ruby 中的 module_function extend self异同

本文主要给大家介绍了在Ruby中 module_function extend self的共同点区别,非常的详细,也很实用,方便大家更好的理解的module_function extend self

Ruby的动态性猴子补丁的双刃剑

Ruby中的class关键字更像是作用域操作符,允许动态地重新打开修改。这种特性,被称为Open Class,可增加灵活性,但同样伴随着风险。本文通过Money gem的示例展示了Open Class的实际应用,并探讨了猴子补丁的利弊,以及对象在Ruby对象模型中的角色。

weixin_35835030的博客 312

Ruby 模块

Module是Class的父: Class.superclass => Modulemodule 没有实例变量 module 没有new不能生成实例对象

产品人生 453

Ruby模块

Ruby是单一继承,一个只能有一个直接的母 Mix-in 模式来处理复合需求 多重包含: 由下往上回溯,重复的只看最上方的 换句话说,程序由上往下执行,由具体到抽象,第二次发现同一个模块就无视 定义 class class-name ... end 注: 实例变量开头@ 变量开头@@ 包含模块用 include...

weixin_30649641的博客 177

210 Ruby 方法、模块【Rails后端开发训练营】

Ruby 方法 什么是方法以及我们为什么需要它 经常会有一段代码需要在程序中多次执行。大多数编程语言中有一个称为过程的功能,而不是一遍又一遍地编写那段代码,它允许你将公共代码提取到一个地方。 在 Ruby 中,我们称之为方法。在我们可以使用一个方法之前,我们必须首先用保留字 def 定义它。在 def 之后我们给我们的方法定义一个名字。在方法定义的最后,我们使用保留字 end 来表示它的完成。这是名为 say 的方法定义的示例: def say # 方法体在这里 end 方法主体中有一条注释,用于向你

Ruby Tips 1045

Ruby快速入门(四):模块

我在第一篇文章里简单的提过对象,但说得太过简单,所以这里重新再说一遍,也加上了对模块的简单介绍。再重申一遍,在Ruby中,一切都是对象,即便是简单的如1、2、3、4这样的数字都是对象。 下面的代码向我们展示了如何使用对象:# 定义class BaseClass # 定义accessor attr_accessor:name # 构

Xizhi Zhu的博客 5720

模块之间的区别

我来自Java,现在我Ruby进行了更多合作。 该module是我不熟悉的一种语言功能。 我想知道module到底是什么,什么时候使用一个module ,为什么要在class使用modu

asdfgh0077的博客 2227

Ruby元编程笔记一

打开 通过 class String def to_alphanumeric gsub /[^\w\s]/,'' end end 可以直接打开已有的并给其添加方法,class关键字的核心任务是把你带入到的上下文中,让你可以定义其中的方法。  如果方法名重合,那么会覆盖原来的方法,这称为“猴子补丁(Moneypatch)”。 对象方法 class M

xieyu33333的专栏 466

ruby元编程——定义

(1)是一个增强的模块,所以所有定义中的特性都同样适用于模块定义。 (2)Ruby程序中总是存在一个当前对象:self,似地,也总有一个当前模块存在,当定义一个方法时,该方法将成为当前的一个实例方法。 (3)当通过class关键字打开一个时,这个就成为当前。 (4)Module#class_eval()方法(module_eval())方法可以在不知道名的情况

401

ruby的层级关系

所有的最终继承于Object,Object本身又继承于 BasicObject。BasicObject是ruby对象体系中的根节点。     'hello'.class =&gt; String String.class =&gt; Class String.superclass =&gt; Object Object.superclass =&gt; BasicOb...

wangsuting.blog 226

ruby 的module

ruby 的module 博客分:  java   ruby模块  Class是Module的子是一种特殊形式的模块, Class, Module, Object,Kernel的关系。  我们知道最顶级的是Object,那么最顶级的模块就是Kernel  我们使用模块的的主要目的是用来组织代码,模块化代码,有点似命名空间,但却有

autumn20080101的专栏 726

ruby 内建关系

我们看到Ruby里,可以直接写puts, print等,感觉像是命令动词一样,这我们说的Ruby里一切都是对象有点冲突,其实我们理解了Ruby中Class, Module,Object,Kernel的关系,就明白了,通过下面的代码,我们知道Module是Class的父. puts Class.ancestors => Class Module Object Kernel Basic...

晗的IT生活 167

Ruby 顶层及 Object、Kernel 的关系

[code="ruby"] http://szsu.wordpress.com/2009/11/07/top_level_object_kernel/ Ruby 的顶层环境、Kernel 模块 Object 之间的关系是一个让很多人都觉得费解的问题,这篇文章便是要对这个话题进行深入的探讨。考虑以下在 Ruby 顶层环境中运行的代码: p "hello" 这...

firedragonpzy 338

Ruby元编程

1.  [].methods == Array.instance_methods //true [].methods.grep /re/ obj.instance_variables //访问一个对象的所有域 Array.instance_methods //访问一个的所有实例方法(不是在对象而是在上调用的) Array.instance_methods(false)//不显示父

qiucheng55的专栏 456

Ruby模块导入 以及includeextend的区别

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34293059的博客 412

Objects and Classes in Ruby

Metaprogramming of Ruby 读书笔记第一章 一、Ruby中关于对象的概念 1、对象:对象是一组实例变量外加一个指向其的引用。对象的方法并不存在于对象本身,而是存在于对象的中。所以这些方法被我们称作的实例方法。 图:对象关系,以及实例方法的归属 2、其实是Class的一个对象,外加一组实例方法一个对其超的引用。Class

陌上 1517

Ruby对象模型总结

参考《Ruby元编程》,元编程,即 用来编写代码的代码 。 对象由一组实例变量一个的引用组成 对象的方法存在对象所属的中,似js中的prototype,在ruby中准确的说,应该是实例方法 本身是Class的队形,的名字不过是常量而已 Class是Module的子模块基本上是由一组方法组成的包。除了具有模块的特性,还可以被实例化,组织为层次结构 常量像文件系统,按照树...

weixin_34080951的博客 208

Ruby之Enumerator

今天发现了Ruby1.8.6 Ruby1.9.2的一个不同之处,试运行以下代码:   require 'find' puts Find.find("./data").class 在Ruby1.9.2中,最后的结果是Enumerator,而在Ruby1.8.6中,结果则是`find': no block given (LocalJumpError) 由此可见Enumerator是R...

JDoc 284

MQTTX-Setup-1.10.0-x64.exe

MQTTX安装文件。MQTTX 是 EMQ 开源的一款跨平台 MQTT 5.0 客户端工具,它支持 macOS, Linux, Windows,并且支持 MQTT 消息格式转换。MQTTX 的用户界面借助聊天软件的形式简化了页面的操作逻辑,用户可以快速创建连接保存并同时建立多个连接客户端,方便用户快速测试 MQTT/TCP、MQTT/TLS、MQTT/WebSocket 的 连接/发布/订阅 功能及其他特性。MQTTX 致力于打造优雅、易用的全平台 MQTT 客户端,并在最近发布了 MQTTX CLI 及 MQTTX Web 两个版本,目前在 GitHub Star 数已达到 2K,已成为使用场景最完整的 MQTT 测试客户端。

上一篇: Install and deploy rails on CentOS
下一篇: Rails ActiveRecord数据库关系1:1
qjpcpu
博客等级 码龄15年 59粉丝 106原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值