侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

详解Ruby中的单件方法和单件类

技术  /  管理员 发布于 5年前   264

单件方法

Ruby允许给单个对象增加方法,这种只针对单个对象生效的方法,称为单件方法

示例代码

str = “just a regular string”def str.title?  self.upcase == selfendstr.title? # => falsestr.methods.grep(/title?/) # => [:title?]str.singleton_methods  #=> [:title?]str.class # => StringString.title? #=> NoMethodError

另外,除了上面使用的定义方法,还可以通过Object#define_singleton_method方法来定义单件方法

单件方法与类方法

前面的笔记中有说道在Ruby中类也是对象,而类名只是常量,所以,在类上调用方法其实跟在对象上调用方法一样:

类方法的实质是: 它是一个类的单件方法,实际上,如果比较单件方法的定义和类方法的定义,会发现其实二者是一样的
 

def obj.a_singleton_method; enddef MyClass.another_class_method; end

二者均使用了def关键词做定义

def object.method  #方法主体end

上面的object可以是*对象的引用、常量类名或者self。

类宏attr_accessor

Ruby对象没有属性,如果希望得到一些像属性的东西,需要分别定义一个读方法和写方法(也就是java、objc中的set和get方法),最直接的可以这样:

示例代码

class MyClass  def my_attribute=(value)    @my_attribute =value    end  def my_attribute    @my_attribute  endendobj = MyClass.newobj.my_attribute = ‘x'obj.my_attribute  #=> ‘x'

但是上面这种写法,如果属性众多的话就会存在Repeat Yourself的地方,这时就可以用到下面三个类宏:

  • Module#attr_reader 生成一个读方法
  • Module#attr_writer 生成一个写方法
  • Module#attr_accessor 同时生成读方法和写方法

示例代码

class MyClass  attr_accessor :my_attribueend

这样是不是就简洁多了呢? 当然,使用方法(读与写)跟上面的实现是一致的。

单件类

我们知道Ruby中对象的方法的查找顺序是: 先向右,再向上,其含义就是先向右找到对象的类,先在类的实例方法中尝试查找,如果没有找到,再继续顺着祖先链找。

前面一篇中有介绍过单件方法,单件方法是指那些只针对某个对象有效的方法,那么如果为一个对象定义了单件方法,那么这个单件方法的查找顺序又应该是怎样的?

class MyClass  def my_method; endendobj = MyClass.newdef obj.my_singleton_method; end

首先,单件方法不会在obj中,因为obj不是一个类,其次它也不在MyClass中,那样的话所有的MyClass都应该能共享调用这个方法,也就构不成单件类了。同理,单件方法也不能在祖先链的某个位置(类似superclass: Object)中。正确的位置是在单件类中,这个类其实就是我们在irb中向对象询问它的类时(obj.class)得到的那个类,不同的是这类与普通的类还是有稍稍不同的。也可以称其为元类或本征类。

打开单件类

Ruby提供了两种方法获取单件类的引用,一种是通过传统的关键词class配合特殊的语法

法一
 

class << an_object  # 自己的代码endobj = Object.newsingleton_class = class << obj  selfendsingleton_class.class # => Class

另一个方法是,通过Object#singleton_class方法来获得单件类的引用:

法二

“abc”.singleton_class  # => #<Class: #<String:0xxxxxx>>

 
单件类的特性

  • 每个单件类只有一个实例(被称为单件类的原因),而且不能被继承
  • 单件类是一个对象的单件方法的存活所在
  • 引入单件类后的方法查找

基于上面对单件类的基本认识,引入单件类后,Ruby的方法查找方式就不应该是先从其类(普通类)开始,而是应该先从对象的单件类中开始查找,如果在单件类中没有找到想要的方法,它才会开始沿着类(普通类)开始,再到祖先链上去找。这样从单件类之后开始,一切又回到了我们在没有引入单件类时候的次序。

通过下面这个代码可以自行验证一下

class C  def a_method    ‘C#a_method()'  endendclass D < C; endobj = D.new

打开单件类定义单件方法

class << obj  def a_singleton_method    ‘obj#a_singleton_method()'  endendobj.singleton_class.superclass #=> D


  • 上一条:
    KB967723造成MySQL频繁无法连接
    下一条:
    Lua脚本语言基本语法快速入门教程
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 2024.07.09日OpenAI将终止对中国等国家和地区API服务(0个评论)
    • 2024/6/9最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(1个评论)
    • 国外服务器实现api.openai.com反代nginx配置(0个评论)
    • 2024/4/28最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(1个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2017-09
    • 2018-01
    • 2018-07
    • 2018-08
    • 2018-09
    • 2018-12
    • 2019-01
    • 2019-02
    • 2019-03
    • 2019-04
    • 2019-05
    • 2019-06
    • 2019-07
    • 2019-08
    • 2019-09
    • 2019-10
    • 2019-11
    • 2019-12
    • 2020-01
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-12
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客