При загрузке пустого файла 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
, который пытается обойти это поведение и предоставить полезный (в этом контексте) запасной вариант:
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
🤔 А знаете ли вы, что...
Ruby позволяет использовать блоки кода для работы с итерациями и коллекциями.