修改局部变量导致全局变量$permission被改动的问题求助
问题原因
Ruby中哈希、数组这类复杂对象采用引用传递。当你执行local_permission = $permission[:packing]时,local_permission并未创建新的哈希副本,而是直接指向$permission[:packing]对应的哈希对象。因此修改local_permission的字段,本质是修改同一个对象,会同步影响全局变量$permission。
解决方法
要让local_permission成为独立对象,需对原哈希做深拷贝,以下是几种可行方案:
1. 用Marshal实现深拷贝(Ruby标准库支持)
通过序列化再反序列化生成完全独立的副本:
$permission = YAML.load_file('permission.yml').deep_symbolize_keys # 生成深拷贝 local_permission = Marshal.load(Marshal.dump($permission[:packing])) local_permission[:create] = ['so1'] # 此时$permission[:packing][:create]不会被修改
2. Rails环境下用deep_dup方法
Rails为哈希、数组内置了deep_dup,专门处理嵌套对象的深拷贝:
$permission = YAML.load_file('permission.yml').deep_symbolize_keys local_permission = $permission[:packing].deep_dup local_permission[:create] = ['so1']
3. 手动递归实现深拷贝(纯Ruby环境可选)
如果不想依赖Marshal或Rails,可以写递归方法处理嵌套结构:
def deep_copy(obj) case obj when Hash obj.each_with_object({}) { |(k, v), h| h[k] = deep_copy(v) } when Array obj.map { |item| deep_copy(item) } else obj.dup rescue obj end end $permission = YAML.load_file('permission.yml').deep_symbolize_keys local_permission = deep_copy($permission[:packing]) local_permission[:create] = ['so1']
内容的提问来源于stack exchange,提问作者Rao Ehtesham
相关产品推荐
相关产品推荐

