%{adj}s %s{holiday}s!
sprintf
is My Favorite Chainsaw
There are a lot of horribly overcomplicated builtins, not just in Perl, but in many languages. Some people like Lisp's format
best -- and why not? Like...
1: | (format nil "~4,'0d-~2,'0d-~2,'0d" 2005 6 10) ; ==> 2005-06-10 |
Right? That's pretty awesome. Then there's Perl's pack
. It's sort of like a sprintf
designed by an assembly programmer who hates you:
1: | pack 'n/a* w/a', 'hello,', 'world'; # gives "\000\006hello,\005world" |
There are actually people who like that, and I have seen, with my own eyes, a guy who defended format
:
1: | format STDOUT_TOP = |
Well, sprintf
isn't as awful as any of these, and that's why I love it... at least if you ignore things like:
1: | # Vectors! |
Enough! Settle down!
Sorry. I got distracted.
sprintf
is the sweet middle ground between a double-quoted string and Template Toolkit. If you stick to the basics that most people use, it's a nice simple way to put placeholders in a string, then stick values into it, doing just a little formatting as needed. Here's how people actually use sprintf
:
1: | printf "Product %s (%s) added for \$%0.2u.\n", |
Nice and simple, right? What I really wanted was a way to use these kinds of templates as templates, outside of code. So, for example, I could store the above string in a configuration file without worrying about the order of arguments:
1: | [Purchasing] |
Then my program could call:
1: | printf $config->{purchasing}{format}, $product; |
String::Formatter is all about building routines that make this possible. It's very flexible, and can probably be tortured into doing all kinds of horrible things (although I hope nobody ever reimplements all of Perl's sprintf
). Here are just a few simple examples of how you can put String::Formatter to use.
object-specific conversions
You can set up format codes that correspond to methods, making a formatting routine that helps convert given objects to strings.
1: | use String::Formatter method_stringf => { |
generic method-calling conversions:
You could write a formatter that just calls any method you want:
1: | use String::Formatter stringf => { |
custom conversions
You could write something meant to be used just like sprintf
, but with different conversion routines:
1: | use String::Formatter stringf => { |
...and you can make it do lots more.
String::Formatter does its job in a few phases, and you can replace each or all of those phases per formatter, so it's easy to write very powerful custom formatting routines. Any time you need to a teeny tiny templating language, consider whether a slightly-improved sprintf
would be enough. You might be surprised how often it will be just right.
See Also
String::Formatter::Cookbook - more detailed examples than seen here
String::Format - String::Formatter's less powerful ancestor
Lisp::Fmt - a Lisp-like formatter that you may not use