At Genius.com, we use YAML to create fixture files for testing DB dependencies. YAML is a great way to easily store many kinds of data in a text file, especially database entries. Despite the incredible ease with which we can write fixtures using YAML, we have found that occasionally YAML does not work quite the way we would expect because of how it parses some data types. Below are several of the “YAML Gotchas” we have run into and a couple more we found while researching data types. Hopefully these can help you avoid some of the debugging that we’ve gone through and illuminate some of YAML’s more interesting features. You can find a full definition of all of the YAML types on YAML’s website.
Note that we’ve come across most of these using the YAML parser Syck for PHP. Keep in mind that although YAML has a specification, not all implementations follow it exactly.
Let’s say you have a survey stored in the database where one column can hold strings, either Yes, No, or Maybe. Your YAML file will look something like this:
survey: recommendAFriend: Yes
After loading this file, you may expect that within survey, you would have a key-value mapping of recommendAFriend to the string Yes. However, you will find that the value Yes has been interpreted by YAML as the boolean value true. In fact, there are many values that YAML will parse into booleans:
y, Y, yes, Yes, YES n, N, no, No, NO true, True, TRUE false, False, FALSE on, On, ON off, Off, OFF
If you want to use any of the above as strings, make sure to explicitly tell YAML to parse it as a string, either by quoting or explicitly casting:
survey: recommendAFriend1: 'Yes' recommendAFriend2: "Yes" recommendAFriend3: !!str Yes
Times and colons
In this survey, you also ask the user what time they usually go to sleep, which you will store in a MySQL time column.
survey: timeSleep: 01:30:00
You may expect this to parse the string 01:30:00 as the value for timeSleep, but instead you will find that it’s the integer 5400. This is because YAML will parse numbers separated by colons as sexagesimal (base 60). This can become even stranger when you try to insert this value into a MySQL database, because MySQL will interpret this integer as a time in the HHMMSS format or even MMSS if it makes sense as a time. In the above example, 5400 will go into the database as 00:54:00. Again, this possible problem can be solved by ensuring that you explicitly cast your times as strings so that they don’t mistakenly get interpreted as integers.
Starting with 0 will cause the number to be parsed in octal as long as you don’t use any digits greater than 7.
survey: customerCode: 01234567
The value for customerCode will parse to the integer 342391.
survey: phoneNumber: 650_212_2050
This feature is not handled by are YAML implementations equally – PHP’s Syck parser interprets the above mentioned phoneNumber key as the string 650_212_2050.
Maximum integer size
Remember that depending on which implementation and which language you use, integers may be bound by the maximum integer size. For example, on a 32-bit machine, any values larger than 2,147,483,647 may be silently converted to that value. This is particularly important to if you use a mixture of 32-bit and 64-bit machines.
According to YAML’s specification: ~, null, Null, NULL, and an empty line are all interpreted as a null value in both values and keys. With Syck in PHP, null keys and their corresponding values are silently ignored because PHP cannot have null as a key. However, with Ruby’s YAML module, null keys will be parsed.
While sometimes helpful, the automatic translation of data types in the YAML specification can be perplexing if you aren’t well versed in what those special data types are. In order to save frustration, it is safest to explicitly mark all data types or at least be familiar with the common pitfalls mentioned above. For sanity’s sake, when debugging applications remember that
even simple complicated things like YAML parsers can be sneaky behind the scenes.