Ruby 环境变量
环境变量是在操作系统中定义的动态值,可以影响程序的运行方式。Ruby提供了多种方式来访问和操作环境变量,本章将详细介绍如何在Ruby中使用环境变量。
🌍 什么是环境变量?
环境变量是操作系统级别的配置参数,它们为运行在系统上的程序提供配置信息。常见的环境变量包括:
- PATH: 可执行文件的搜索路径
- HOME: 用户主目录
- USER: 当前用户名
- LANG: 系统语言设置
- RUBY_ENV: Ruby应用程序环境(development, production, test)
📦 访问环境变量
使用ENV对象
Ruby通过内置的ENV对象来访问环境变量,它是一个类似哈希的对象:
ruby
# 获取环境变量
home_dir = ENV['HOME']
user_name = ENV['USER']
path = ENV['PATH']
puts "主目录: #{home_dir}"
puts "用户名: #{user_name}"
puts "路径: #{path}"
# 检查环境变量是否存在
if ENV.has_key?('RUBY_ENV')
puts "Ruby环境: #{ENV['RUBY_ENV']}"
else
puts "未设置RUBY_ENV环境变量"
end
# 获取所有环境变量
puts "所有环境变量:"
ENV.each do |key, value|
puts "#{key}: #{value}"
end安全访问环境变量
ruby
# 提供默认值
database_url = ENV.fetch('DATABASE_URL', 'sqlite://localhost/default.db')
api_key = ENV.fetch('API_KEY') { 'default-api-key' }
# 检查是否存在
if ENV.key?('SECRET_KEY')
secret_key = ENV['SECRET_KEY']
else
puts "警告: 未设置SECRET_KEY环境变量"
secret_key = 'default-secret'
end
# 使用三元运算符
debug_mode = ENV['DEBUG'] ? ENV['DEBUG'] == 'true' : false🛠️ 设置环境变量
在Ruby程序中设置
ruby
# 设置环境变量
ENV['MY_APP_NAME'] = 'My Ruby Application'
ENV['APP_VERSION'] = '1.0.0'
# 验证设置
puts "应用名称: #{ENV['MY_APP_NAME']}"
puts "应用版本: #{ENV['APP_VERSION']}"
# 删除环境变量
ENV.delete('MY_APP_NAME')
puts "应用名称: #{ENV['MY_APP_NAME']}" # nil在不同操作系统中设置
Linux/macOS系统
bash
# 临时设置(当前会话有效)
export DATABASE_URL="postgresql://localhost/myapp"
export API_KEY="your-api-key-here"
# 在shell脚本中设置
#!/bin/bash
export RUBY_ENV=production
ruby my_app.rb
# 在.bashrc或.zshrc中永久设置
echo 'export RUBY_ENV=development' >> ~/.bashrc
source ~/.bashrcWindows系统
cmd
# 命令行设置(当前会话有效)
set DATABASE_URL=postgresql://localhost/myapp
set API_KEY=your-api-key-here
# PowerShell设置
$env:RUBY_ENV="production"
# 永久设置(系统环境变量)
# 通过系统属性 -> 高级 -> 环境变量设置🎯 常用Ruby环境变量
Ruby相关环境变量
ruby
# RUBY_ENV - 应用程序环境
ruby_env = ENV.fetch('RUBY_ENV', 'development')
case ruby_env
when 'development'
puts "开发环境模式"
when 'production'
puts "生产环境模式"
when 'test'
puts "测试环境模式"
else
puts "未知环境: #{ruby_env}"
end
# RUBYLIB - Ruby库路径
ruby_lib_path = ENV['RUBYLIB']
puts "Ruby库路径: #{ruby_lib_path}" if ruby_lib_path
# RUBYOPT - Ruby命令行选项
ruby_options = ENV['RUBYOPT']
puts "Ruby选项: #{ruby_options}" if ruby_options
# GEM_PATH - Gem搜索路径
gem_path = ENV['GEM_PATH']
puts "Gem路径: #{gem_path}" if gem_path
# GEM_HOME - Gem安装目录
gem_home = ENV['GEM_HOME']
puts "Gem主目录: #{gem_home}" if gem_home应用程序环境变量
ruby
# 数据库配置
database_url = ENV.fetch('DATABASE_URL') do
case ENV.fetch('RUBY_ENV', 'development')
when 'development'
'sqlite://localhost/development.db'
when 'test'
'sqlite://localhost/test.db'
when 'production'
raise "必须设置DATABASE_URL环境变量"
end
end
# API密钥
api_key = ENV.fetch('API_KEY') do
puts "警告: 使用默认API密钥(仅用于开发)"
'default-api-key'
end
# 服务器配置
server_port = ENV.fetch('PORT', 3000).to_i
server_host = ENV.fetch('HOST', 'localhost')
puts "服务器配置: #{server_host}:#{server_port}"🛡️ 环境变量安全
敏感信息处理
ruby
class Config
# 敏感环境变量列表
SENSITIVE_VARS = %w[
DATABASE_URL
API_KEY
SECRET_KEY
PASSWORD
PRIVATE_KEY
].freeze
def self.get(key, default = nil)
value = ENV[key]
return default if value.nil? || value.empty?
value
end
def self.get_required(key)
value = ENV[key]
raise "必须设置环境变量: #{key}" if value.nil? || value.empty?
value
end
def self.safe_display
ENV.each do |key, value|
if SENSITIVE_VARS.any? { |sensitive| key.upcase.include?(sensitive) }
puts "#{key}: ********" # 隐藏敏感信息
else
puts "#{key}: #{value}"
end
end
end
end
# 使用示例
begin
db_url = Config.get_required('DATABASE_URL')
api_key = Config.get('API_KEY', 'default-key')
puts "配置加载成功"
rescue => e
puts "配置错误: #{e.message}"
end环境变量验证
ruby
class EnvironmentValidator
def self.validate_required(vars)
missing = []
vars.each do |var|
missing << var unless ENV[var] && !ENV[var].empty?
end
unless missing.empty?
raise "缺少必需的环境变量: #{missing.join(', ')}"
end
end
def self.validate_format(var, pattern, description = nil)
value = ENV[var]
return true if value.nil? || value.empty?
unless value.match?(pattern)
desc = description || "#{var}格式不正确"
raise "环境变量验证失败: #{desc}"
end
true
end
def self.validate_numeric(var, min = nil, max = nil)
value = ENV[var]
return true if value.nil? || value.empty?
begin
num = Integer(value)
if min && num < min
raise "环境变量#{var}必须大于等于#{min}"
end
if max && num > max
raise "环境变量#{var}必须小于等于#{max}"
end
rescue ArgumentError
raise "环境变量#{var}必须是数字"
end
true
end
end
# 使用示例
begin
# 验证必需的环境变量
EnvironmentValidator.validate_required(['DATABASE_URL', 'API_KEY'])
# 验证邮箱格式
EnvironmentValidator.validate_format('ADMIN_EMAIL',
/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i,
'管理员邮箱格式不正确')
# 验证端口号
EnvironmentValidator.validate_numeric('PORT', 1, 65535)
puts "环境变量验证通过"
rescue => e
puts "环境变量验证失败: #{e.message}"
exit 1
end📁 环境配置管理
使用配置文件
ruby
require 'yaml'
class EnvironmentConfig
def self.load_config(config_file = 'config.yml')
# 加载配置文件
config = YAML.load_file(config_file) rescue {}
# 合并环境变量
env = ENV.fetch('RUBY_ENV', 'development')
config.merge(config[env] || {})
end
def self.database_config
{
url: ENV.fetch('DATABASE_URL') { default_database_url },
pool: ENV.fetch('DB_POOL_SIZE', 5).to_i,
timeout: ENV.fetch('DB_TIMEOUT', 5000).to_i
}
end
private
def self.default_database_url
case ENV.fetch('RUBY_ENV', 'development')
when 'development'
'sqlite://localhost/development.db'
when 'test'
'sqlite://localhost/test.db'
when 'production'
raise "生产环境必须设置DATABASE_URL"
end
end
end
# config.yml示例
=begin
---
development:
database_url: sqlite://localhost/dev.db
api_key: dev-key
debug: true
production:
debug: false
test:
database_url: sqlite://localhost/test.db
api_key: test-key
=end
# 使用配置
config = EnvironmentConfig.load_config
puts "数据库URL: #{config['database_url']}"环境特定配置
ruby
class AppConfig
def self.environment
@environment ||= ENV.fetch('RUBY_ENV', 'development')
end
def self.development?
environment == 'development'
end
def self.production?
environment == 'production'
end
def self.test?
environment == 'test'
end
def self.log_level
if development?
'debug'
elsif production?
'warn'
else
'info'
end
end
def self.cache_enabled?
return false if development?
ENV.fetch('CACHE_ENABLED', 'true') == 'true'
end
def self.worker_processes
if production?
ENV.fetch('WORKER_PROCESSES', 4).to_i
else
1
end
end
end
# 根据环境配置应用
puts "当前环境: #{AppConfig.environment}"
puts "日志级别: #{AppConfig.log_level}"
puts "缓存启用: #{AppConfig.cache_enabled?}"
puts "工作进程数: #{AppConfig.worker_processes}"🧪 环境变量测试
测试环境变量
ruby
# 测试环境变量设置和获取
RSpec.describe 'Environment Variables' do
before do
@original_env = ENV.to_hash
end
after do
ENV.replace(@original_env)
end
it 'should get environment variable' do
ENV['TEST_VAR'] = 'test_value'
expect(ENV['TEST_VAR']).to eq('test_value')
end
it 'should provide default value' do
expect(ENV.fetch('NON_EXISTENT_VAR', 'default')).to eq('default')
end
it 'should handle required variables' do
expect { ENV.fetch('REQUIRED_VAR') }.to raise_error(KeyError)
end
end
# 简单的测试脚本
def test_environment_variables
puts "=== 环境变量测试 ==="
# 测试基本操作
ENV['TEST_VAR'] = 'test_value'
puts "设置测试变量: #{ENV['TEST_VAR']}"
# 测试默认值
default_value = ENV.fetch('NON_EXISTENT', 'default')
puts "默认值测试: #{default_value}"
# 测试存在性检查
exists = ENV.key?('PATH')
puts "PATH变量存在: #{exists}"
# 清理测试变量
ENV.delete('TEST_VAR')
puts "清理测试变量完成"
puts "=== 测试完成 ==="
end
# 运行测试
test_environment_variables if __FILE__ == $0🎯 最佳实践
1. 使用dotenv管理开发环境变量
ruby
# Gemfile
# gem 'dotenv-rails' # Rails应用
# gem 'dotenv' # 普通Ruby应用
# .env文件示例
=begin
# 开发环境配置
DATABASE_URL=sqlite://localhost/development.db
API_KEY=dev-api-key
DEBUG=true
SECRET_KEY=dev-secret-key
=end
# 加载dotenv(在应用启动时)
require 'dotenv/load' if development?
# 访问环境变量
database_url = ENV['DATABASE_URL']
api_key = ENV['API_KEY']2. 环境变量文档化
ruby
# environment_variables.rb
class EnvironmentVariables
# 应用程序环境变量文档
VARIABLES = {
'DATABASE_URL' => {
description: '数据库连接URL',
required: true,
default: nil,
example: 'postgresql://user:pass@localhost/dbname'
},
'API_KEY' => {
description: '第三方API密钥',
required: false,
default: 'default-key',
example: 'sk-xxxxxxxxxxxxxxxxxxxxxxxx'
},
'PORT' => {
description: '服务器端口',
required: false,
default: '3000',
example: '3000'
},
'RUBY_ENV' => {
description: '应用程序环境',
required: false,
default: 'development',
example: 'development|production|test'
}
}.freeze
def self.document
puts "应用程序环境变量说明:"
puts "=" * 50
VARIABLES.each do |name, info|
puts "变量名: #{name}"
puts " 描述: #{info[:description]}"
puts " 必需: #{info[:required] ? '是' : '否'}"
puts " 默认: #{info[:default] || '无'}"
puts " 示例: #{info[:example]}"
puts
end
end
end
# 生成文档
# EnvironmentVariables.document3. 环境隔离
ruby
class EnvironmentManager
def self.setup_environment
case ENV.fetch('RUBY_ENV', 'development')
when 'development'
setup_development
when 'production'
setup_production
when 'test'
setup_test
else
puts "未知环境: #{ENV['RUBY_ENV']}"
end
end
private
def self.setup_development
puts "设置开发环境"
# 开发环境特定配置
end
def self.setup_production
puts "设置生产环境"
# 生产环境特定配置
disable_debug_output
enable_caching
end
def self.setup_test
puts "设置测试环境"
# 测试环境特定配置
end
def self.disable_debug_output
# 禁用调试输出
end
def self.enable_caching
# 启用缓存
end
end
# 应用启动时调用
EnvironmentManager.setup_environment📚 下一步学习
掌握了Ruby环境变量的使用后,建议继续学习:
- Ruby 变量 - 深入了解Ruby中的各种变量类型
- Ruby 数据类型 - 学习Ruby的数据类型系统
- Ruby 配置管理 - 学习更高级的配置管理技术
- Ruby 应用部署 - 了解生产环境中的环境变量管理
继续您的Ruby学习之旅吧!