Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

An Idiot's Guide to YAML

by scorpio17 (Abbot)
on Jun 08, 2007 at 20:01 UTC ( #620076=perlmeditation: print w/replies, xml ) Need Help??

I recently discovered YAML and thought it was very cool, so I've been anxiously awaiting a chance to actually use it. Well, I just started a new project and I thought YAML would be perfect for loading the config file.

I immediately had problems, because the YAML parser was unable to read in my config file. It gave me an error saying 'stream does not end with newline' - which left me perplexed because the file did, indeed, have a newline!

Since the problem seemed to be with the YAML syntax, I thought it would be clever to make Perl generate the file for me. I hardcoded a data structure in Perl and wrote out YAML using the Dump() command:

# use strict; use warnings; use YAML; my $config = { NAME => 'John Doe', ADDRESS => '123 Main St.', PHONE => { 'Home' => '123-4444', 'Work' => '123-5555', }, CONTACTS => [ 'John', 'Paul', 'George', ], }; print Dump( $config ), "\n";

I saved the output as config.yml, which looks like this:

--- ADDRESS: 123 Main St. CONTACTS: - John - Paul - George NAME: John Doe PHONE: Home: 123-4444 Work: 123-5555

This looked pretty much like what I already had, and sure enough, when I tried reading it back in, I again got the same error as before. This is what my reader script looked like:

# -- does NOT work! use strict; use warnings; use YAML; use Data::Dumper; # load YAML file into perl hash ref? my $config = Load("config.yml"); print Dumper($config), "\n";

I am too ashamed to admit on this board how long it took me to figure out the problem here, but I DID read the docs on cpan, search on google, search here, and search on the official yaml site, to no avail.

Here's the solution - which I'm posting here on the off chance that someone, some where, some day, may have the same bad fortune that I did, and will find this helpful.

# - Works! Yippie! use strict; use warnings; use YAML; use Data::Dumper; # step 1: open file open my $fh, '<', 'config.yml' or die "can't open config file: $!"; # step 2: slurp file contents my $yml = do { local $/; <$fh> }; # step 3: convert YAML 'stream' to perl hash ref my $config = Load($yml); print Dumper($config), "\n";

And there you have it: the Load function does not load a FILE, it loads a STREAM. Okay - so now I feel like an idiot. But I went back and read the documentation again, and this really is not that obvious. An example would have helped a bunch. There wasn't one there, but now there's one here.


After going back and very carefully reading the docs a third time (after bossman's replay) I finally found what I was really looking for all along - the LoadFile function:

# - Works also! Yippie! use strict; use warnings; use YAML; use Data::Dumper; # step 1: open file open my $fh, '<', 'config.yml' or die "can't open config file: $!"; # step 2: convert YAML file to perl hash ref my $config = LoadFile($fh); print Dumper($config), "\n";

'You're Welcome' in advance...

Replies are listed 'Best First'.
Re: An Idiot's Guide to YAML
by hossman (Prior) on Jun 08, 2007 at 20:23 UTC

    For the record, the perldoc for the "YAML" module starts with an example which shows the method Load using the here doc syntax to parse a string. I don't disagree that example complicates the explanation of how the Load command works, but it also clearly states in the "FUNCTIONAL USAGE" section...

    Load(string-containing-a-YAML-stream) Turn YAML into Perl data. This is the opposite of Dump. Just like Storable's thaw() function or the eval() function in relation to Data::Dumper. It parses a string containing a valid YAML stream into a list of Perl data structures.

    It also says...

    LoadFile(filepath) Reads the YAML stream from a file instead of a string.
Re: An Idiot's Guide to YAML
by perrin (Chancellor) on Jun 08, 2007 at 20:39 UTC
    Given that you were able to write a 100% working config in perl immediately and the one in YAML took longer than you care to admit, I wonder why you bothered to use YAML. Is there someone who has to edit this that will be put off by a perl config but not by a YAML one?
      Why bother? Good question! Most likely no one will use this but me. Like I said before, I had read about YAML and thought that it was cool. I wanted to learn something new. It should NOT have taken any longer to write than any other config reader. Maybe I'm the only one who ever had this problem? I did find a lot of hits when I googled for it... I think the root of the problem was a) I'm used to using other config file readers, and they all load based on filename, not file contents; b) after a quick scan of the docs, I thought I knew what I was doing; c) the error message I got led me off in the wrong direction.

      I'm fairly new to perlmonks and haven't made many contributions, and thought someone might appreciate the examples.

        Oh, don't get me wrong. Your post is very welcome, and we're glad to have you here. I was mostly interested in what your motivation was because I personally find YAML kind of pointless. It looks a lot harder to work with than most of the other config choices to me. Nevertheless, it seems to be very popular in certain camps.
      How was he supposed to know it was going to take him a long time to do it in YAML? A lot of people (inlcluding me) talk up YAML config-file solutions as being relatively simple.

      Most programming tasks have a large indeterminancy about how long they'll take -- even the simple ones (like this) sometimes run into some odd hang-up (that leave you feeling like an idiot for spending a day on something that was supposed to take five minutes).

        Sure, he couldn't know he would hit this problem. I wondered what problem he was trying to solve by switching to YAML.
      It seems that the problem he had was not with the YAML config, but with reading the documentation. However, in answer to your question about why I would bother to use YAML, let me give you an example.

      In my current project, I have a large amount of config, stored in a directory tree containing 59 separate YAML files, for ease of management.

      I loaded and merged (with Config::Loader) all of this data, and then printed it out to two separate files, one with YAML::Syck and one with Data::Dumper. Both were set to use two spaces as an indent.

      YAML Perl Perl > YAML ------------------------------------ Lines 3279 4150 27% Size 85 kB 139 kB 63% Size (no spaces) 49 kB 66 kB 35%
      While some would argue that the last measure is irrelevant, because YAML requires white space, I would say that it IS relevant because, to be legible and maintainable, Perl also needs white space. Instead those numbers are a measure of the extra punctuation that is needed to represent your data - the more punctuation, the less visible is the stuff that actually matters.

      In practice, I've added a lot of extra white space and comment lines etc, so that my actual config is 3350 lines and 105kB - still a good deal smaller than a compact Perl version. And the extra stuff is either unobtrusive (whitespace) or obviously not part of the actual data (comments). I would assume a similar growth in size if I were to do the same thing in Perl.

      People complain about how difficult it is to edit YAML by hand, a sentiment I do not understand at all. The format is simple and easy to read. This example covers 95% of my configuration needs:

      scalar: value array: - element 1 - element 2 - element 3 hash: key1: value1 key2: value2 key3: value3

      There is a lot more you can do with it, such as referencing other data structures within the YAML, recursion, loading Perl code, here docs and multiline scalars. However, most of this is unnecessary for day to day usage.

      The one thing that seem to trip people up is the whitespace. YAML doesn't accept tabs as whitespace and, in my opinion, this is a good thing. How wide is a tab? PBP recommends using spaces for indenting Perl code instead of tabs for this very reason. And quite frankly, if your Perl indentation is a mess, it's going to be difficult to maintain anyway. Clear indentation makes for legibility. Any editor that uses spaces for tabs and can do block indents will handle YAML with ease.

      Opinions about YAML are strongly polarised, and I'm not suggesting that it is the One True Way. But there are a lot of nay-sayers that give YAML a bad reputation, and I think it is undeserved. It is a very flexible, easy, useful and widely available format, and in my opinion, deserves its place at the table.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://620076]
Approved by imp
Front-paged by GrandFather
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2017-10-23 03:24 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (276 votes). Check out past polls.