Контекст
При загрузке пустого файла YAML возвращается false
.Я не хочу обсуждать, имеет ли это поведение смысл или его следует изменить - это обсуждение уже имеет место.Некоторые примеры:
YAML.load("") #=> false
YAML.load("\n") #=> false
YAML.load(" \n") #=> false
И для контекста:
YAML.load("false") #=> false
YAML.load("---") #=> nil
YAML.load("null"). #=> nil
YAML.load("nil") #=> "nil"
Я нашел этот код в ActiveSupport::EncryptedConfiguration
, который пытается обойти это поведение и предоставляет полезный(в этом контексте) fallback:
def deserialize(config)
config.present? ? YAML.load(config, content_path) : {}
end
И на первый взгляд кажется, что это может сработать, потому что config.present?
(с config
строкой YAML) вернет false
для всех примероввыше:
"".present? #=> false
"\n".present? #=> false
" \n".present? #=> false
Но здесь есть одна загвоздка: это содержание примера EncryptedConfiguration
файла , сгенерированного самими Rails:
def encrypted_file_template
<<-YAML.strip_heredoc
# aws:
# access_key_id: 123
# secret_access_key: 345
YAML
end
Потому что
"# aws:\n# access_key_id: 123\n# secret_access_key: 345\n" => true
не не запускает откат к {}
синтаксическому анализу, который приведен в примере , этот метод
def config
@config ||= deserialize(read).deep_symbolize_keys
end
с NoMethodError: undefined method 'deep_symbolize_keys' for false:FalseClass
исключение.
Вопрос
Я хочу вернуть запасной вариант, например {}
вместо false
, когда строка, переданная в YAML.load
, не содержит никакого полезного синтаксиса YAML.Но в ситуациях, когда false
является действительным ответом (например, YAML.load("false")
), я не хочу возвращать запасной вариант.
Есть ли лучший способ вернуть запасной вариант, чем этот?
value = YAML.load(yaml)
return FALLBACK if value == false && yaml.strip != "false"
value