当前位置: 首页 > news >正文

Ruby模块和程序组织

和类一样,模块是一组方法和常量的集合。
和类不同,模块没有实例,取而代之的是可以将特殊模块的功能添加到一个类或者指定对象之中。
Class类是Module类的一个子类,因此每一个类对象也是一个模块对象

一、模块创建和基础应用

编写一个模块和编写类差不多,只是用module关键字在定义开始的位置取代class关键字而已。
Ruby模块是一种代码重用的方式,可以用来定义可重用的代码片段。模块中的方法可以被其他Ruby类或模块使用,就像它们是类的一部分一样。模块的名字就是模块的标识符,它不需要与文件名相同。
下面是一个创建和使用Ruby模块的基本示例:

# 创建一个模块  
module MyModule  def my_method  "Hello, World!"  end  
end  # 在另一个类中使用这个模块  
class MyClass  include MyModule  def call_my_method  my_method  end  
end  # 创建一个对象并调用方法  
obj = MyClass.new  
puts obj.call_my_method # 输出 "Hello, World!"

在这个例子中,我们首先定义了一个名为MyModule的模块,其中包含一个名为my_method的方法。然后,我们在MyClass中通过include MyModule语句将这个模块包含进来。这样,我们就可以在MyClass中使用MyModule中的方法了。最后,我们创建了一个MyClass的对象,并调用了call_my_method方法,该方法内部调用了我们定义的my_method方法。

Ruby模块对于代码的组织和重用非常有用。它们可以包含一组相关的函数,这些函数可以在多个不同的类或对象中使用。通过使用模块,我们可以避免在多个地方重复编写相同的代码,并且可以使代码更加清晰、易于理解和维护。

1、使用模块封装一个栈

模块提供了一种收集和封装行为的方式。一个典型的模块包含一些方法,这些方法最终将会与拥有对象全部功能的一个特定子集关联。
栈是一种后进先出的数据结构,当设计一个程序,以及定义一种行为或行为的集合时,这些行为可能会被多个类型的实体或对象表现出来,这时模块就是一种好的备选方案。

module Stacklikedef stack@stack ||= []enddef add_to_stack(obj)stack.push(obj)enddef take_from_stackstack.popend
end

2、将模块混合到类中

模块没有实例,不能直接new一个。

require_relative "stacklike"
class Stackinclude Stacklike
end

注意类名是一个名词,而模块名称是一个形容词

二、模块、类和方法查找

1、方法查找

清晰地理解对象发现方法的方式是件有趣的事。看下面这个例子:

module M def reportputs "'report' method in module M"end
endclass C include M 
endclass D < C 
endobj = D.new
obj.report

实例方法report被定义在模块M中。而模块M被混合到了类C中。类D是C的子类,obj是D的一个实例。通过这样的层级关系,对象obj便可以访问report方法。

2、同名方法的多次定义

在类中定义一个方法两次,第二个定义将会取代第一次。这在模块中依然如此。
对象的方法可以从任意数量的类和模块中获得。
一个对象在其查找路径中有两个同名方法的另一种情况是:当一个类混合了两个或多个模块时,将搜索到方法的多个实现。这样的例子中,按照包含的逆序查找模块,这意味着最新混合到类中的模块将最先被搜索到。假如最新混合得到类的模块包含一个同名的方法,其方法在早先被混合的模块中出现过,最新被混合的模块中的那个版本的方法将会占据优先级,因为新混合的模块在查找路径中有最短的距离。

module M def reportputs "'report' method in module M"end
endmodule N def reportputs "'report' method in module N"end 
endclass C include M include N 
endc = C.new
c.report

这将会输出'report' method in module N
但是在包含N之后再次包含M

class C include M include N include M
endc = C.new
c.report

这仍将会输出'report' method in module N。因为M已经存在于查找路径中,第二次包含M没有任何效果。N仍然被认为是最新引入的模块。

3、prepend

在Ruby中,prepend是一个方法,用于将一个模块或类添加到另一个类的继承链中。它使得被prepend的模块或类的方法在原类的方法之前被调用。

module MeFirstdef reportputs "Hello from module!"end
endclass Personprepend MeFirstdef reportputs "Hello from class!"end
endp = Person.new
p.report

运行这段代码将会输出

Hello from module!

4、方法查找的顺序

为了将消息解析为可用的方法,对象会在如下位置搜索方法
1、被前置在它所属类中的模块,按照与前置相反的顺序。
2、它的类中
3、被包含在它所属类中的模块,按照与包含相反的顺序
4、前置到它超类中的方法,按照与包含相反的顺序
5、它所属的超类
6、包含在它所属超类中的模块
7、同样地,达到Object和BasicObject

5、使用super向上追溯方法路径

在Ruby中,super关键字用于调用父类中的方法。当子类重写父类的方法时,使用super可以调用父类中被重写的方法。

class ParentClass  def method  "Parent method"  end  
end  class ChildClass < ParentClass  def method  super.method + " child method"  end  
end  child = ChildClass.new  
puts child.method # 输出 "Parent method child method"

三、method_missing方法

method_missing是Ruby语言中的一个特殊方法。当试图调用一个不存在的方法时,Ruby会自动调用method_missing方法。这个方法允许你实现自定义的行为来处理缺失的方法调用。

class MyClass  def method_missing(method_name, *args)  if method_name.to_s == "hello"  "Hello, World!"  else  super  end  end  
end  obj = MyClass.new  
obj.hello # 输出 "Hello, World!"  
obj.foo   # 抛出 NoMethodError 异常,因为方法 "foo" 不存在

在上面的示例中,当调用obj.hello时,由于MyClass类中没有定义名为hello的方法,Ruby会自动调用method_missing方法。在method_missing方法中,我们根据方法名进行判断,如果方法名是"hello",则返回"Hello, World!“,否则调用super方法来抛出异常。这样,当我们调用obj.hello时,会得到预期的输出结果"Hello, World!”。而当我们尝试调用一个不存在的方法如obj.foo时,会抛出NoMethodError异常。
使用method_missing方法可以实现在运行时动态处理缺失的方法调用,提供了很大的灵活性和扩展性。但需要注意的是,过度使用method_missing可能会导致代码难以理解和维护,因此在使用时需要权衡利弊。

相关文章:

Ruby模块和程序组织

和类一样&#xff0c;模块是一组方法和常量的集合。 和类不同&#xff0c;模块没有实例&#xff0c;取而代之的是可以将特殊模块的功能添加到一个类或者指定对象之中。 Class类是Module类的一个子类&#xff0c;因此每一个类对象也是一个模块对象 一、模块创建和基础应用 编写…...

14、SpringCloud -- WebSocket 实时通知用户

目录 实时通知用户需求:代码:前端:后端:WebSocket创建 websocket-server 服务添加依赖:配置 yml 和 启动类:前端:后端代码:注意:测试:总结:实时通知用户 需求: 用户订单秒杀成功之后,对用户进行秒杀成功通知。 弹出个提示框来提示。 代码: 前端:...

智能井盖传感器推荐,万宾科技助力城市信息化建设

随着科技产品更新换代进程加快&#xff0c;人工智能在人们日常生活之中逐渐普及开来&#xff0c;深入人们生活的方方面面&#xff0c;影响城市基础设施建设工程。例如在大街小巷之中的井盖作为城市基础建设的一个重要部分&#xff0c;一旦出现松动倾斜或凸起等异常问题&#xf…...

3D模型格式转换工具HOOPS Exchange对工业级3D产品HOOPS的支持与应用

一、概述 HOOPS Exchange是一套高性能模型转换软件库&#xff0c;可以给软件提供强大的模型的导入和导出功能&#xff0c;我们可以将其单独作为转换工具使用&#xff0c;也可以将其集成到自己的软件中。 同样&#xff0c;HOOPS 的其它产品&#xff0c;也离不开HOOPS Exchange…...

table 表体滚动, 表头、表尾固定

在开发报表中&#xff0c;如果报表数据行过多页面无法全部显示&#xff0c;或者内容溢出div&#xff0c;需要把表头和表尾固定表体滚动这样就可以在页面上全部显示&#xff0c;并且不会溢出div 效果&#xff1a;最终实现效果 代码&#xff1a;<!DOCTYPE html> <html&g…...

第57篇-某钩招聘网站加密参数分析【2023-10-31】

声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、网站分析1.X-S-HEADER参数2.请求参数data3.响应机密值data一、前言 网址: aHR0cHM6Ly93d3cubGFnb3UuY29t…...

C语言数据结构之数据结构入门

目录 数据结构介绍 数据结构发展史 何为算法 数据结构基础 基本概念和术语 四大逻辑结构&#xff08;Logic Structure&#xff09; 数据类型 理解复杂度概念 时间空间复杂度定义 度量时间复杂度的方法 程序运行时的内存与地址 编程预备 数据结构介绍 数据结构发展…...

如何知道服务器的某个端口是否打开

1、telnet 命令&#xff1a;telnet ip port&#xff0c;port即端口&#xff0c;我们一般最常见的命令就是telnet&#xff0c;但是telnet使用的是tcp协议&#xff0c;换句话说telnet只能检测tcp的这个端口打开了没 若是端口打开&#xff0c;会出现下列信息 失败的是这个 如…...

【ICCV‘23】One-shot Implicit Animatable Avatars with Model-based Priors

文章目录 前置知识 前置知识 1&#xff09;SMPL模型 \quad SMPL这类方法只建模穿很少衣服的人体&#xff08;裸体模型&#xff09;&#xff0c;它只能刻画裸体角色的动画&#xff0c;并不能刻画穿衣服的人体的动画 2&#xff09;data-efficient \quad 这个词推荐用&#xff…...

关于息肉检测和识别项目的总结

前言 整体的思路&#xff1a;首先息肉数据集分为三类&#xff1a; 1.正常细胞 2. 增生性息肉 3. 肿瘤要想完成这个任务&#xff0c;首先重中之重是分割任务&#xff0c;分割结果的好坏&#xff0c; 当分割结果达到一定的准确度后&#xff0c;开始对分割后的结果进行下游分类…...

Jetson Xavier NX FFmpeg支持硬件编解码

最近在用Jetson Xavier NX板子做视频处理,但是CPU进行视频编解码,效率比较地下。 于是便考虑用硬解码来对视频进行处理。 通过jtop查看,发现板子是支持 NVENC硬件编解码的。 1、下载源码 因为需要对ffmpeg进行打补丁修改,因此需要编译两份源码 1.1、编译jetson-ffmpeg …...

518抽奖软件,为什么说比别的抽奖软件更美观精美?

518抽奖软件简介 518抽奖软件&#xff0c;518我要发&#xff0c;超好用的年会抽奖软件&#xff0c;简约设计风格。 包含文字号码抽奖、照片抽奖两种模式&#xff0c;支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 精致美观功能 字体平滑无锯齿图片放大后清晰…...

React的组件学习

React的组件学习 参考资料&#xff1a;https://zh-hans.react.dev/learn/your-first-component 一、定义组件 export default function Profile() {return (<imgsrc"https://i.imgur.com/MK3eW3Am.jpg"alt"Katherine Johnson"/>) }以下是构建组件…...

uni-app配置微信开发者工具

一、配置微信开发者工具路径 工具->设置->运行配置->小程序运行配置->微信开发者工具路径 二、微信开发者工具开启服务端口...

肺癌不再是老年病:33岁作家的离世引发关注,有这些情况的请注意

近期&#xff0c;90后网络小说家七月新番和26岁男艺人蒋某某因肺癌去世&#xff0c;引发关注。他们都没有吸烟习惯&#xff0c;那么他们为什么会得肺癌呢&#xff1f;浙大二院呼吸内科副主任医师兰芬说&#xff0c;现在年轻人熬夜、加班导致身体过劳&#xff0c;在劳累情况下身…...

【兔子王赠书第4期】用ChatGPT轻松玩转机器学习与深度学习

文章目录 前言机器学习深度学习ChatGPT推荐图书粉丝福利尾声 前言 兔子王免费赠书第4期来啦&#xff0c;突破传统学习束缚&#xff0c;借助ChatGPT的神奇力量&#xff0c;解锁AI无限可能&#xff01; 机器学习 机器学习是人工智能领域的一个重要分支&#xff0c;它的目的是让…...

Ubuntu18.04 ROS Melodic的cv_bridge指向问题(四种方式,包括opencv4)(转载)

转载自&#xff1a; 【精选】Ubuntu18.04 ROS Melodic的cv_bridge指向问题&#xff08;四种方式&#xff0c;包括opencv4&#xff09;_XiangrongZ的博客-CSDN博客...

Android任务栈和启动模式

Andrcid中的任务栈是一种用来存放Activity实倒的容器。任务最大的特点就是先进后出&#xff0c;它主要有两个基本操作&#xff0c;分别是压栈和出栈。通常Andaid应用程序都有一个任务栈&#xff0c;每打开一个Activity时&#xff0c;该Activity就会被压入任务栈。每销毁一个Act…...

电脑加密软件哪个好?电脑加密软件推荐

电脑是我们办公离不开的工具&#xff0c;而为了保护电脑数据安全&#xff0c;我们可以使用专业的电脑加密软件来进行加密保护。那么&#xff0c;电脑加密软件哪个好呢&#xff1f;下面我们就来了解一下。 文件加密——超级加密3000 想要安全加密电脑重要文件&#xff0c;我们可…...

如何优雅地单元测试 Kotlin/Java 中的 private 方法?

翻译自 https://medium.com/mindorks/how-to-unit-test-private-methods-in-java-and-kotlin-d3cae49dccd ❓如何单元测试 Kotlin/Java 中的 private 方法❓ 首先&#xff0c;开发者应该测试代码里的 private 私有方法吗&#xff1f; 直接信任这些私有方法&#xff0c;测试到…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...