Read more

When loading Yaml contents in Ruby, use the :freeze argument to deep-freeze everything

Arne Hartherz
January 18, 2024Software engineer at makandra GmbH

Ruby methods which load from a Yaml file, like YAML.safe_load or YAML.safe_load_file, support passing freeze: true to deep-freeze the entire contents from the Yaml file.
This is available by default on Ruby 3.0 and newer. On older Rubies, you can install psych 3.2.0 or newer for :freeze support.

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

As an example, consider the following Yaml file:

---
message:
  - hello
  - universe
foo:
  bar:
    baz: "example"

We can now load it as usual, but pass freeze: true.

>> test = YAML.safe_load_file('example.yml', freeze: true)
=> {"message"=>["hello", "universe"], "foo"=>{"bar"=>{"baz"=>"example"}}}

The Hash itself is frozen:

>> test.frozen?
=> true

And no matter how deep you dig, everything inside that Hash is also frozen.

>> test['message'].frozen?
=> true
>> test['foo']['bar']['baz'].frozen?
=> true

Loading from a file likely means that its contents should be considered immutable (e.g. a configuration), so we recommend you use freeze: true almost always.
Especially use this instead of YAML.safe_load_file(...).freeze which will not freeze any nested objects.

Posted by Arne Hartherz to makandra dev (2024-01-18 09:09)