2

I have a YAML config file where I want to include specific ruby class/module constants instead of the actual value.

For example, instead of putting "loglevel: 0" in the config file, I want "loglevel: Logger::DEBUG".

Is there a way to have YAML decode or resolve a class or module constant like Logger::DEBUG?

This is what I've been playing with, but looking at the psych ruby code, I don't see anything that might support this.

config.yml

loglevel: !ruby/class:fixnum Logger::DEBUG

In irb

irb> require 'logger'

irb> config = YAML.load_file('config.yml')

config['loglevel'] contains "Logger::DEBUG" as a String instead of the actual value.

I can do an eval on it like so:

irb> p eval config['loglevel'] 0 ==> 0

I'm just wondering if there's a way to have YAML eval it? I'm okay with doing it in my code after doing a YAML load, but I wanted to make sure I left no stone unturned in my, what has turned into a lengthy, quest ;-).

lauracw100
  • 93
  • 1
  • 6

2 Answers2

3

Not sure of a YAML way, but best not to use eval...

In Ruby 2+

Object.const_get 'Logger::DEBUG'

Or the old school

def const_lookup const_name
  const_name.split('::').inject(Object) do |rec, name|
    rec.const_get(name)
  end
end

const_lookup 'Logger::DEBUG'
Matt
  • 68,711
  • 7
  • 155
  • 158
1

Looks like you can do it for classes/modules but not their constants

2.0.0-p247 :046 > YAML.load("!ruby/class 'String'")
 => String 
2.0.0-p247 :047 > YAML.load("!ruby/class 'String'").class
 => Class 
2.0.0-p247 :065 > YAML.load("!ruby/class 'Logger'")
 => Logger 
Mark Silverberg
  • 1,249
  • 2
  • 8
  • 21