NAME
Text::Printf - A simple, lightweight text fill-in class.
VERSION
This documentation describes version 1.00 of Text::Printf, March 26, 2008.
SYNOPSIS
printf
-like usage:
# Print (to default filehandle, or explicit filehandle).
tprintf ($format, \%values);
tprintf ($filehandle, $format, \%values)
# Render to string.
$result = tsprintf ($format, \%values);
Prepared-template usage:
# Create a template:
$template = Text::Printf->new($format, \%options);
# Set default values:
$template->default(\%values);
# Set some override values:
$template->pre_fill(\%values);
# Fill it in, rendering the result string:
$result = $template->fill(\%values);
OPTIONS
delimiters => [ '{{', '}}' ]; # may be strings
delimiters => [ qr/\{\{/, qr/\}\}/ ]; # and/or regexps
DESCRIPTION
There are many templating modules on CPAN. They're all far, far more powerful than Text::Printf. When you need that power, they're wonderful. But when you don't, they're overkill.
This module provides a very simple, lightweight, quick and easy templating mechanism for when you don't need those other powerful-but-cumbersome modules.
There are two ways to use this module: an immediate (printf-like) way, and a delayed (prepared) way.
For the immediate way, you simply call "tprintf" or "tsprintf" with a boilerplate string and the values to be inserted/formatted. See the following section for information on how to format the boilerplate string. This is somewhat easier than using plain printf
or sprintf
, since the name of the value to be inserted is at the same place as its format.
For the prepared way, you create a template object that contains the boilerplate text. Again, see the next section for information on how to format it properly. Then, when it is necessary to render the final text (with placeholders filled in), you use the "fill" method, passing it one or more references of hashes of values to be substituted into the original boilerplate text. The special value $DONTSET
indicates that the keyword (and its delimiters) are to remain in the boilerplate text, unsubstituted.
That's it. No control flow, no executable content, no filesystem access. Never had it, never will.
TEMPLATE FORMAT
When you create a template object, or when you use one of the printf-like functions, you must supply a template, which is a string that contains placeholders that will be filled in later (by the "fill" method). All other text in the template will remain undisturbed, as-is, unchanged.
Examples:
'This is a template.'
'Here's a placeholder: {{fill_me_in}}'
'Can occur multiple times: {{name}} {{phone}} {{name}}'
'Optionally, can use printf formats: {{name:20s}} {{salary:%.2f}}'
'Fancier formats: {{salary:%.2f:,$}}'
Substitution placeholders within the text are indicated by keywords, set off from the surrounding text by a pair of delimiters. By default the delimters are {{
and }}
, because that's easy to remember, and since double curly braces are rare in programming languages (and in natural languages).
Keywords between the delimiters must be comprised entirely of "word" characters (that is, alphabetics, numerics, and the underscore), and there must be no spaces or other characters between the keyword and its delimiters. This strictness is considered a feature.
Each keyword may optionally be followed (still within the delimiters) by a colon (:
) and a printf format. If a format is specified, it will be used to format the entry when expanded. The format may omit the leading %
symbol, or it may include it.
If a printf format is supplied, it may optionally be followed by another colon and zero or more special "extended formatting" characters. Currently, two such characters are recognized: ,
(comma) and $
(dollar sign). Each of these is only useful if the placeholder is being replaced by a number. If a comma character is used, commas will be inserted every three positions to the left of the decimal point. If a dollar-sign character is used, a dollar sign will be placed immediately to the left of the first digit of the number.
A printf format may be preceeded by a "-
" sign to indicated that the string or number is to be left-justified within the field width. The default is right-justification. (This is how all printf
s work) I personally have a hard time remembering that. So instead of a minus sign, you can use a less-than sign ("<
") to indicate left- justification, or a greater-than sign (">
") to indicate right-justification.
So, to sum up, the following are examples of valid printf-style formats:
d integer
x hexadecimal
5d integer, right-justified, minimum 5 positions
-5d integer, left-justified, minimum 5 positions
<5d Same
>5d Same, only right-justified
.2f floating-point, two decimal places
.10s string, maximum 10 positions
10.10s string, exactly 10 positions, right-justified
<10.10s string, exactly 10 positions, left-justified
COMMON MISTAKE
If Text::Printf does not expand a placeholder, check to make sure that you did not include any spaces around the placeholder name, and did not use any non-"word" (regex \W
) characters in the name. Text::Printf is very strict about spaces and other characters; this is so that a non-placeholder does not get expanded by mistake.
Right: {{lemon}}
Right: {{pi:%.9f}}
Wrong: {{ lemon }}
Wrong: {{lemon pie}}
Right: {{lemon_pie}}
Wrong: {{pi: %.9f}}
Text::Printf will silently leave incorrectly-formatted placeholders alone. This is in case you are generating code; you don't want something like
sub foo {{bar => 1}};
to be mangled or to generate errors.
METHODS
- new
-
Constructor.
$template_object = Text::Printf->new($boilerplate, \%options);
Creates a new Text::Printf object. The boilerplate text string parameter is mandatory; the hashref of options is optional.
Currently, the only option permitted is
delimiters
, which is a reference to an array of two strings (or compiled regular expresions): a starting delimiter and an ending delimiter. - fill
-
Render the formatted string.
$result_string = $template->fill($hashref); $result_string = $template->fill($hashref, $hashref, ...);
Replaces all of the placeholders within the template with values from the hashref(s) supplied.
For each placeholder, the hashrefs are examined in turn for a matching key. As soon as one is found, the template moves on to the next placeholder. Another way of looking at this behavior is "The first hashref that fulfills a given placeholder... wins."
If the resulting value is the special constant
$DONTSET
, the placeholder is left intact in the template.If no value for a placeholder is found among any of the hash references passed, an exception is thrown.
- pre_fill
-
Set values without rendering.
$template->pre_fill($hashref, ...);
Specifies one or more sets of key=>value pairs to be used by the "fill" method in addition to (and higher priority than) the ones passed to "fill".
This can be useful if some template values are set when the template is created, but the template is filled elsewhere in the program, and you don't want to pass variables around.
- default
-
Set default values without rendering.
$template->default($hashref, ...);
Like "pre_fill", specifies key=>value pairs to be used by "fill", but where "pre_fill"'s values have a higher priority than those specified by "fill", "default"'s are lower. This can be used at the time the object is created to give default values that only get used if the call to "fill" (or "pre_fill") don't override them.
- clear_values
-
Clear default and pre-filled values.
$template->clear_values();
Removes any "pre_fill"ed or "default" hash references in the object.
FUNCTIONS
- tprintf
-
Render and print.
tprintf $format, \%values
Like Perl's printf, tprintf takes a format string and a list of values. Unlike Perl's printf, the placeholders and values have names. Like Perl's printf, the result string is sent to the default filehandle (usually STDOUT).
This is equivalent to:
my $template = Text::Printf->new ($format); print $template->fill (\%values);
tprintf returns the same value as printf.
If the first argument is a filehandle, or any sort of object that supports a
print
method, output is sent there instead of to the default filehandle.The original inspiration for this module came as the author was scanning through a long and complex list of arguments to a printf template, and lost track of which value when into which position.
- tsprintf
-
Render to string.
$string = tsprintf $format, \%values; $string = tsprintf $filehandle, $format, \%values;
Same as "tprintf", except that it returns the formatted string instead of sending it to the default filehandle.
This is equivalent to:
$string = do { my $t = Text::Printf->new($format); $t->fill (\%values) };
EXAMPLES
$book_t = Text::Printf->new('<i>{{title}}</i>, by {{author}}');
$bibl_1 = $book_t->fill({author => "Stephen Hawking",
title => "A Brief History of Time"});
# yields: "<i>A Brief History of Time</i>, by Stephen Hawking"
$bibl_2 = $book_t->fill({author => "Dr. Seuss",
title => "Green Eggs and Ham"});
# yields: "<i>Green Eggs and Ham</i>, by Dr. Seuss"
$bibl_3 = $book_t->fill({author => 'Isaac Asimov'});
# Dies with "Could not resolve the following symbol: title"
$bibl_4 = $book_t->fill({author => 'Isaac Asimov',
title => $DONTSET });
# yields: "<i>{{title}}</i>, by Isaac Asimov"
# Example using format specification:
$report_line = Text::Printf->new('{{Name:-20s}} {{Grade:10d}}');
print $report_line->fill({Name => 'Susanna', Grade => 4});
# prints "Susanna 4"
$line = tsprintf '{{Name:-20s}} {{Grade:10d}}', {Name=>'Gwen', Grade=>6};
# $line is now "Gwen 6"
tprintf *STDERR, '{{number:-5.2f}}', {number => 7.4};
# prints "7.40 " to STDERR.
# Example using extended formatting characters:
$str = tsprintf '{{widgets:%10d:,}} at {{price:%.2f:,$}} each',
{widgets => 1e6, price => 1234};
# $str is now: " 1,000,000 at $1,234.00 each"
EXPORTS
This module exports the following symbols into the caller's namespace:
$DONTSET
tprintf
tsprintf
REQUIREMENTS
This module is dependent upon the following other CPAN modules:
Readonly
Exception::Class
DIAGNOSTICS
Text::Printf uses Exception::Class objects for throwing exceptions. If you're not familiar with Exception::Class, don't worry; these exception objects work just like $@
does with die
and croak
, but they are easier to work with if you are trapping errors.
All exceptions thrown by Text::Printf have a base class of Text::Printf::X. You can trap errors with an eval block:
eval { $letter = $template->fill(@hashrefs); };
and then check for errors as follows:
if (Text::Printf::X->caught()) {...
You can look for more specific errors by looking at a more specific class:
if (Text::Printf::X::KeyNotFound->caught()) {...
Some exceptions provide further information, which may be useful for your exception handling:
if (my $ex = Text::Printf::X::OptionError->caught())
{
warn "Bad option: " . $ex->name();
...
If you choose not to (or cannot) handle a particular type of exception (for example, there's not much to be done about a parameter error), you should rethrow the error:
if (my $ex = Text::Printf::X->caught())
{
if ($ex->isa('Text::Printf::X::SomethingUseful'))
{
...
}
else
{
$ex->rethrow();
}
}
Parameter errors
Class:
Text::Printf::X::ParameterError
You called a Text::Printf method with one or more bad parameters. Since this is almost certainly a coding error, there is probably not much use in handling this sort of exception.
As a string, this exception provides a human-readable message about what the problem was.
Option errors
Class
Text::Printf::X::OptionError
There's an error in one or more options passed to the constructor "new".
This exception has one method,
name()
, which returns the name of the option that had a problem (for example, 'delimiters
').As a string, this exception provides a human-readable message about what the problem was.
Unresolved symbols
Class
Text::Printf::X::KeyNotFound
One or more subsitution keywords in the template string were not found in any of the value hashes passed to "fill", "pre_fill", or "default". This exception is thrown by "fill".
This exception has one method,
symbols()
, which returns a reference to an array containing the names of the keywords that were not found.As a string, this exception resolves to
"Could not resolve the following symbols:"
followed by a list of the unresolved symbols.Internal errors
Class
Text::Printf::X::InternalError
Something happened that I thought couldn't possibly happen. I would be grateful if you would send me an email message detailing the circumstances of the error.
AUTHOR / COPYRIGHT
Copyright (c) 2005-2008 by Eric J. Roode, ROODE -at- cpan -dot- org
All rights reserved.
To avoid my spam filter, please include "Perl", "module", or this module's name in the message's subject line, and/or GPG-sign your message.
This module is copyrighted only to ensure proper attribution of authorship and to ensure that it remains available to all. This module is free, open-source software. This module may be freely used for any purpose, commercial, public, or private, provided that proper credit is given, and that no more-restrictive license is applied to derivative (not dependent) works.
Substantial efforts have been made to ensure that this software meets high quality standards; however, no guarantee can be made that there are no undiscovered bugs, and no warranty is made as to suitability to any given use, including merchantability. Should this module cause your house to burn down, your dog to collapse, your heart-lung machine to fail, your spouse to desert you, or George Bush to be re-elected, I can offer only my sincere sympathy and apologies, and promise to endeavor to improve the software.