psych icon indicating copy to clipboard operation
psych copied to clipboard

Bug: aliases & nested keys unexpected behavior

Open WoutDev opened this issue 11 months ago • 0 comments

Description

Today I encountered a rather weird bug in my project, and tracked it down to how YAML handles nested keys with aliases. I noticed how changing a specific key in a Hash from YAML.load(_file) would change multiple values instead.

Given that the YAML.load(_file) method returns a Hash, changing one specific key of that Hash should not change any other key. Or at least that is the behavior I'm expecting. I couldn't find any documentation regarding this odd behavior.

I have only observed this odd behavior with nested keys, not 'normal' keys as demonstrated below.

Steps to reproduce

require 'yaml'

yaml = <<YAML
alias: &alias
  normal_value: 404
  nested:
    value: 404

some_key:
  <<: *alias
  
another_key:
  <<: *alias
YAML

content = YAML.load(yaml, aliases: true, symbolize_names: true)
puts "========== BEFORE =========="
pp content

content[:alias][:normal_value] = 999
content[:alias][:nested][:value] = 999

puts "========== AFTER =========="
pp content

When running this script, I'm getting the following output:

========== BEFORE ==========
{alias: {normal_value: 404, nested: {value: 404}}, some_key: {normal_value: 404, nested: {value: 404}}, another_key: {normal_value: 404, nested: {value: 404}}}
========== AFTER ==========
{alias: {normal_value: 999, nested: {value: 999}}, some_key: {normal_value: 404, nested: {value: 999}}, another_key: {normal_value: 404, nested: {value: 999}}}

Notice how the nested value is modified in both some_key and another_key, while the normal value is not.

Machine details

  • Apple M3 Macbook Air
  • Reproduced on: "ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin24]", "ruby 3.4.0dev (2024-12-25 master f450108330) +PRISM [arm64-darwin24]"

WoutDev avatar Feb 02 '25 21:02 WoutDev