Ruby 开发(五) - 模块(中)

394 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

三、加载外部文件

loadrequire

在 Ruby 脚本中可以通过 loadrequire 关键字来加载外部文件,首先在新建一个 alpha 文件夹,在该文件夹中新建 alpha.rb 脚本,在该脚本中新建一个 Module Alpha

module Alpha
  def info
    puts "info 方法"
  end

  def self.show
    puts "show 类方法"
  end
end

Alpha.show

在 alpha 文件夹的同级目录下新建一个脚本 bravo.rb,在该脚本中加载 Alpha 模块

puts "加载 alpha 文件夹中的 alpha 脚本中的 Alpha 模块"
load 'alpha/alpha.rb'

执行上述代码,输出结果如下:

加载 alpha 文件夹中的 alpha 脚本中的 Alpha 模块
show 类方法

require 关键字的功能比 load 关键字更加强大,不仅可以加载 Ruby 源文件,还可以加载其他语言编写的源文件,require 的语法格式如下:

require "源文件"
require "源文件全名"

新建 zulu.rb 文件,定义一个方法 zulu_fun

def zulu_fun
  puts "Hello, Zulu"
end

同级目录下新建一个 yankee.rb 文件,使用 require 关键字导入 zulu.rb

# 调用zulu中的代码

require "#{File.dirname(__FILE__)}/zulu"
zulu_fun
zulu_fun

执行上述代码,输出结果如下:

Hello, Zulu
Hello, Zulu

require 加载的方法可以重复使用,但是只会加载一次文件,load 方法可以多次加载文件。

includeextend

include 方法主要是讲一个模块混合到一个类中,以此来访问模块中共的实例成员,extend 方法主要是用来在一个对象中引入一个模块,这个类也就具备了这个模块的方法,类似继承,如果想要使用模块中的方法成为类的类方法时,就需要使用的 extend 方法

module WiskeyM
  def say
    puts "Hello"
  end
end

class Person
  extend WiskeyM
end

person = Person.new
person.extend(WiskeyM)
person.say

执行上述代码,输出结果如下:

Hello

四、别名 alias 和定义

别名的定义

Ruby 中存在一种为方法定义别名的机制,Ruby 标准库为别名和定义的修改提供了关键字,使用这些关键字可以定义别名、判断是否完成定义、释放定义等

为方法或者全局变量添加别名需要使用到 alias 关键字,还可以使用到 Module 类中的 alias_method 给方法添加别名。

def alpha
  puts "alpha 方法"
end

# 定义别名
alias bravo alpha

def alpha
  puts "重新定义的 alpha 方法"
end

puts alpha
puts bravo

执行上述代码,输入内容如下:

重新定义的 alpha 方法

alpha 方法

调用新定义的别名输出的结果是未定义别名之前的内容,别名定义之后,在定义一个与原名字相同的方法也不会报错,类似于变量指向,只不过这里执行的是方法而不是具体的值。

定义的操作

Ruby 中对定义的操作主要有:判断定义是否完成和释放定义量大操作

判断某个表达式是否已经完成定义需要使用到 defined? 语法,如果表达式已经完成定义则会返回 false,否则返回一个保存表达式类型的字符串。

defined?表达式
class Animal
  def info
    puts "Hello"
    puts defined?"Hi"
  end
end

animal = Animal.new
puts defined?animal.info
animal.info

执行上述代码,输出结果如下:

method
Hello
expression

defined?animal.info 返回的是 method,这是因为 animal.info 的类型是一个方法,而类中的 defined?"Hi" 返回的是 expression 这是因为 defined? 后面跟的是一个表达式。

defined? 的返回值有很多,如下:

返回的字符串解释说明
"super"当 super 调用时返回的字符串
"method"判断已经定义的方法时返回的字符串
"yield"当 yield 可用时返回的字符串
"self"当 self 可用时返回的字符串
"nil"当对象为 nil 是返回的字符串
"true"当表达式为 true 返回的字符串
"false"当表达式为 true 返回的字符串
"assignment"当一个局部已定义但未赋值是返回的字符串
"local-variable"当一个局部已赋值是返回的字符串
"local-variable(m-block)"当一个局部已赋值且处于一个代码块中时返回的字符串
"global-variable"当一个全局变量已被赋值时返回的字符串
"instance-variable"当一个实例变量已被赋值时返回的字符串
"constant"当一个常量已被赋值时返回的字符串
"class-variable"当一个类变量已被赋值时返回的字符串
"express"只是一个表达式时返回的字符串

使用 undef 关键字可以释放定义,可以同时释放一个或者多个方法

undef 方法名
class Fly
  def go
    puts "going"
  end
end

fly = Fly.new
undef go
puts defined?fly.go

执行上述代码,返回结果如下:

Traceback (most recent call last):
/ruby-module/ex9.rb:8:in `<main>': undefined method `go' for class `Object' (NameError)

undef 关键字将类中的 go 方法释放了定义,所以再次调用 go 方法的时候出现了报错。