Ruby Programming | 连载 04 - Ruby 扩展基础

简介: Ruby Programming | 连载 04 - Ruby 扩展基础

一、Ruby 的安装目录

Ruby Programming | 连载 01 - Intro and Setup 中展示了通过 rvm 安装 Ruby 的过程,安装 Ruby 不仅会安装 ruby 解释器,还安装了 Ruby 语言支持的库和文件,在使用 ruby 解释器执行代码时都能够成功找到所需要的文件或者目录。

要获取 Ruby 的安装目录位置可以在 irb 解释器中加载 rbconfig 库来获取。rbconfig 是一个接口,通过该接口可以获取 Ruby 的各种安装和配置信息。

irb --simple-prompt -r rbconfig
复制代码

-rrequire 的简写,表示用来加载 rbconfig 库,在成功加载 rbconfig 库之后就可以获取 Ruby 的各种配置信息了。

>> RbConfig::CONFIG["bindir"]
=> "/Users/maverick/.rvm/rubies/ruby-2.7.6/bin"
复制代码

RbConfig::CONFIG 是一个 Hash 散列表,类似 Python 中的 Map 字典,是一种 K-V 结构的数据,根据输入的键 bindir 就可以获取相应的值。

当然 RbConfig::CONFIG 中的键值对有多个,除了 bindir 之外,还有:

RbConfig::CONFIGKey 对应的 Value 的说明
rubylibdir Ruby 标准库
archdir 已编译的扩展库和文件
sitedir User 自定义的第三方库和文件(Ruby 编写)
vendordir 安装的第三方的扩展库和文件(Ruby 编写)
sitelibdir User 自定义的扩展(Ruby 编写)
sitearchdir User 自定义的扩展(C 编写)

irb 解释器中获取到的配置信息:

image.png

Ruby 的标准库子目录 RbConfig::CONFIG["rubylibdir"]

rubylibdir 目录中存储了 Ruby 编写的标准库文件,可以通过 require 关键字加载这些文件,常用的标准库文件如下:

  • cgi.rb:CGI 编程工具库
  • fileutils.rb:文件操作工具
  • tempfile.rb:自动创建临时目录的机制
  • drb.rb:分布式编程工具
  • date.rb:时间日期库
  • io.rb:IO 库
  • logger.rb:logger 库

image.png

仅仅使用 rubylibdir 中的提供的库就可以完成许多功能。

Ruby 的 C 扩展目录 RbConfig::CONFIG["archdir"]

archdir 目录中包含了特定架构的扩展和库文件,都是以 .bundle 结尾的 C 语言扩展文件,它们都是二进制文件,用户不可读但是 ruby 解释器可以读懂,只有在运行时可以加载。

image.png

Ruby 程序中使用这些由 C 语言编写的标准库的方式也是使用 require 关键字加载。

User 自定义的 Ruby 的扩展库 RbConfig::CONFIG["rubylibdir"] 和 User 安装的第三方的扩展库 Ruby 的标准库子目录 RbConfig::CONFIG["rubylibdir"]

site_rubyvendor_ruby 目录中包含了是用于自定义的库或者是通过 gem 工具安装的第三方的库。

gems 目录

RubyGems 工具是打包和发布 Ruby 库文件的标准方式,相当于 Java 中的 Maven,用户可以使用 gem 工具来安装第三方的扩展。当用户安装 gems 时,未绑定的库文件会放置在 gems 目录中。

二、Ruby 的扩展库

安装 Ruby 是一同安装的扩展通常成为 Ruby 的标准库,与 Python 的标准库一样,Ruby 的中的大量标准库也提供了非常多的功能或者扩展,包括数据库管理、网络、数据分析等。标准库精密的结构每次改变,都要随着 Ruby 新版本的发布而发布,而使用最多最广泛的库则已经趋于稳定。

使用标准库和第三方扩展的关键字是 require,除此之外还可以使用 load 方法,这些方法可以在运行时加载标准库或者第三方扩展。

加载外部文件和第三方扩展 load

在编写大型的 Ruby 应用时,不可能将所有的代码放在一个文件中,我们需要将程序功能拆分,每个功能后者几个功能单独放在一个文件中,而加载或者引用这些单独文件中所编写的功能就需要使用到 requireload

首先来看 load 的使用,新建一个 buy.rb 文件,包含如下代码:

puts "罗老师说要一个中杯的拿铁"
load "coffee.rb"
puts "罗老师疯了...."
复制代码

该代码中通过 load 方法加载了 coffee.rb 文件,在同级目录下创建 coffee.rb,代码如下:

puts "服务员:对不起先生,这个是大杯"
puts "服务员:这个才是中杯"
puts "服务员:中杯、大杯、特大杯"
复制代码

执行 buy.rb,输出结果如下:

罗老师说要一个中杯的拿铁
服务员:对不起先生,这个是大杯
服务员:这个才是中杯
服务员:中杯、大杯、特大杯
罗老师疯了....
复制代码

load 的使用非常简单,后面要跟具体的 Ruby 文件的名称,要加双引号且不能省略扩展名,ruby 解释器可以根据名称找到加载的文件,如果不在同级目录,ruby 解释器将在加载路径中找到。

ruby 解释器的加载路径是一些列目录的集合,ruby 将在这些目录中搜索指定的文件名,使用 load 加载文件时可以使用相对路径也可以使用绝对路径。

load 是一个方法,只要执行到 load 这行代码是才会加载指定的文件,出现几次 load 就加载几次,并且几次加载同一个文件时最新的文件将会覆盖之前加载的文件。

请求 require

require 是一个关键字,load 是一个方法,load 在代码中可以多次执行相同的文件,而 require 不会加载已经加载过的文件。

修改 buy.rb,使用 require 关键字,修改后的代码如下:

puts "罗老师说要一个中杯的拿铁"
require "./coffee.rb"
puts "罗老师疯了...."
复制代码

执行 buy.rb 文件,输出结果如下:

罗老师说要一个中杯的拿铁
服务员:对不起先生,这个是大杯
服务员:这个才是中杯
服务员:中杯、大杯、特大杯
罗老师疯了....
复制代码

使用 require 时要选择相对路径,统计目录下直接使用文件名会报错:

puts "罗老师说要一个中杯的拿铁"
require "coffee.rb"
puts "罗老师疯了...."
复制代码

执行 buy.rb 文件,控制台报错信息如下:

罗老师说要一个中杯的拿铁
Traceback (most recent call last):
  2: from /ruby-tutorial/buy.rb:2:in `<main>'
  1: from /Users/maverick/.rvm/rubies/ruby-2.7.6/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
/Users/maverick/.rvm/rubies/ruby-2.7.6/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require': cannot load such file -- coffee.rb (LoadError)
复制代码

require 关键字加载用户自定义的 Ruby 文件是不能辨识出当前的工作目录,一定要显示的指定路径。

require 用于请求 Ruby 的标准库和第三方库,此时不需要指定标准库或者第三方库的路径。

require_relative

require_relative 会搜索相对于当前文件所在的目录来加载,修改 buy.rb 文件为如下内容:

puts "罗老师说要一个中杯的拿铁"
require_relative "coffee.rb"
puts "罗老师疯了...."
复制代码

执行 buy.rb 代码,输出结果与之前内容保持一致。


相关文章
|
Java C++ Ruby
Ruby Programming | 连载 06 - Ruby 面向对象
Ruby Programming | 连载 06 - Ruby 面向对象
Ruby Programming | 连载 06 - Ruby 面向对象
Ruby Programming | 连载 08 - Ruby 方法参数
Ruby Programming | 连载 08 - Ruby 方法参数
Ruby Programming | 连载 08 - Ruby 方法参数
Ruby Programming | 连载 07 - Ruby 对象的原生行为
Ruby Programming | 连载 07 - Ruby 对象的原生行为
Ruby Programming | 连载 07 - Ruby 对象的原生行为
|
存储 IDE 开发工具
Ruby Programming | 连载 03 - Ruby 对象基础
Ruby Programming | 连载 03 - Ruby 对象基础
Ruby Programming | 连载 03 - Ruby 对象基础
|
IDE Java Linux
Ruby Programming | 连载 01 - Intro and Setup
Ruby Programming | 连载 01 - Intro and Setup
Ruby Programming | 连载 01 - Intro and Setup
|
存储 Ruby
Ruby Programming | 连载 10 - Ruby 的类
Ruby Programming | 连载 10 - Ruby 的类
|
Scala Ruby
Ruby Programming | 连载 09 - Ruby 变量
Ruby Programming | 连载 09 - Ruby 变量
|
Linux 数据库 Ruby
Ruby Programming | 连载 05 - Ruby 工具集
Ruby Programming | 连载 05 - Ruby 工具集
|
存储 对象存储 Ruby
Ruby Programming | 连载 02 - Ruby 语法基础
Ruby Programming | 连载 02 - Ruby 语法基础