说些题外话。人生真 TMD 的痛苦...今天没设闹铃,一下子就比平时多睡了一个小时。有时候会想,这么强迫自己是否值得。 我们都太期望成功,以至于逼迫的自己不行
今天我们要认识的是 Ruby 中的 ENV
这个对象。我们将介绍与 Env
相关的下列几个知识点:
ENV
对象ENV
和 C 语言标准库函数ENV
对象的实现
ENV 对象
ENV 对象是操作环境变量的一个 Ruby API 接口。
就像操作哈希表 ( HASH ) 一样,ENV 对象提供了一组方法来添加,更改,删除和访问 Ruby 友好的环境变量
irb-001> ENV['AN_ENV_VARIABLE'] = 'cool!' => "cool!" irb-002> ENV['AN_ENV_VARIABLE'] => "cool!" irb-003> ENV['AN_ENV_VARIABLE'] = 'great!' => "great!" irb-004> ENV.delete('AN_ENV_VARIABLE') => "great!" irb-005> ENV.fetch('AN_ENV_VARIABLE', 'a default value') => "a default value"
上面的示例中,我们可以看到 ENV API 的简单用法
- 使用
ENV.[]=
方法将环境变量AN_ENV_VARIABLE
的值设置为cool!
- 使用
ENV.[]
方法获取环境变量AN_ENV_VARIABLE
的值 - 使用
ENV.[]=
方法将环境变量AN_ENV_VARIABLE
的值设置为great!
- 使用
ENV.delete
方法删除环境变量AN_ENV_VARIABLE
- 使用
ENV.fetch
方法获取环境变量AN_ENV_VARIABLE
的值,如果不存在的话,则返回传递的第二个参数
看起来非常酷对吧,但系统环境变量到底在哪儿呢 ?
ENV 和 C 语言标准库函数
ENV 对象依赖于 C 语言标准库函数 来管理环境变量
例如,当我们调用 ENV.[]
方法时,Ruby 会根据我们的操作系统调用相应的 C 标准库函数 - 例如,对于类 UNIX 的操作系统,会直接调用 getenv(3)
- 来获取适当的环境变量
该系统效率高,依赖于强大的标准库。
另外,ENV 对象只用于操控 Ruby 程序运行时的环境变量。Ruby 程序启动时,内存中没有预先加载环境变量
因此,你是不是和我一样好奇,Ruby 内部是如何实现 Ruby 的
ENV 对象的实现
ENV 是类哈希 ( HASH ) 对象。这意味着即使它是 Object 的一个实例,仍有着一堆类似于 Hash 实例的方法
irb> ENV.class => Object
在 Ruby 内部,ENV 对象重新编码类似哈希的方法 ( 如 ENV[ENVIRONMENT_VARIABLE]
) 以便可以使用 env(3)
C 函数族。因此 ENV 对象只是 C 函数的 Ruby 包装器,负责管理环境变量
此外,ENV 对象扩展了 Enumerable
模块,重写了该模块的一堆方法,例如 each
和 each_pair
irb> ENV.singleton_class.included_modules => [Enumerable, Kernel]
因此,总结一下,可以说 ENV
对象是存储在全局常量中的 Object 的 「 可枚举 」 实例
更多相关信息,你可以直接阅读 Ruby 的 C 语言源码