1String::Print(3)      User Contributed Perl Documentation     String::Print(3)
2
3
4

NAME

6       String::Print - printf alternative
7

SYNOPSIS

9         ### Functional interface
10
11         use String::Print;           # simpelest way
12         use String::Print qw/printi printp/, %config;
13         printi 'age {years}', years => 12;
14
15         # interpolation of arrays and hashes (serializers)
16         printi 'price-list: {prices}', prices => \@p, _join => "+";
17         printi 'dump: {c}', c => \%config;
18
19         # same with positional parameters
20         printp 'age %d", 12;
21         printp 'price-list: %.2f', \@prices;
22         printp 'dump: %s', \%settings;
23
24         # modifiers
25         printi 'price: {price%.2f}', price => 3.14*VAT*EURO;
26
27         # [0.91] more complex interpolation names
28         printi 'filename: {c.filename}', c => \%config;
29         printi 'username: {user.name}', user => $user_object;
30         printi 'price: {product.price €}', product => $db->product(3);
31
32         ### Object Oriented interface
33
34         use String::Print 'oo';      # import nothing
35         my $f = String::Print->new(%config);
36         $f->printi('age {years}', years => 12);
37         $f->printp('age %d', 12);
38
39         ### via Log::Report's __* functions (optional translation)
40
41         use Log::Report;             # or Log::Report::Optional
42         print __x"age {years}", years => 12;
43
44         ### via Log::Report::Template (Template Toolkit extension)
45
46         [% SET name = 'John Doe' %]
47         [% loc("Dear {name},") %]     # includes translation
48

DESCRIPTION

50       This module inserts values into (format) strings.  It provides "printf"
51       and "sprintf" alternatives via both an object oriented and a functional
52       interface.
53
54       Read in the "DETAILS" chapter below, why this module provides a better
55       alternative for "printf()".  Also, some extended examples can be found
56       down there.  Take a look at them first, when you start using this
57       module!
58

METHODS

60   The Object Oriented interface
61       See functions printi(), sprinti(), printp(), and sprintp(): you can
62       also call them as method.
63
64         use String::Print 'oo';
65         my $f = String::Print->new(%config);
66         $f->printi($format, @params);
67
68         # exactly the same functionality:
69         use String::Print 'printi', %config;
70         printi $format, @params;
71
72       The Object Oriented interface wins when you need the same configuration
73       in multiple source files, or when you need different configurations
74       within one program.  In these cases, the hassle of explicitly using the
75       object has some benefits.
76
77       Constructors
78
79       String::Print->new(%options)
80            -Option     --Default
81             encode_for   undef
82             missing_key  <warning>
83             modifiers    [ qr/^%\S+/ = \&format_printf]>
84             serializers  <useful defaults>
85
86           encode_for => HASH|'HTML'
87             [0.91] The format string and the inserted values will get encoded
88             according to some syntax rules.  For instance,
89             "encode_entities()" of HTML::Entities when you specify the
90             predefined string "HTML".  See encodeFor().
91
92           missing_key => CODE
93             [0.91] During interpolation, it may be discovered that a key is
94             missing from the parameter list.  In that case, a warning is
95             produced and "undef" inserted.  May can overrule that behavior.
96
97           modifiers => ARRAY
98             Add one or more modifier handlers to power of the formatter.
99             They will get preference over the predefined modifiers, but lower
100             than the modifiers passed to "print[ip]" itself.
101
102           serializers => HASH|ARRAY
103             How to serialize data elements.
104
105           example:
106
107             my $f = String::Print->new
108               ( modifiers   => [ EUR   => sub {sprintf "%5.2f e", $_[0]} ]
109               , serializers => [ UNDEF => sub {'-'} ]
110               , encode_for  => 'HTML'
111               );
112
113             $f->printi("price: {p EUR}", p => 3.1415); # price: ␣␣3.14 e
114             $f->printi("count: {c}", c => undef);      # count: -
115
116       Attributes
117
118       $obj->addModifiers(PAIRS)
119           The PAIRS are a combination of an selector and a CODE which
120           processes the value when the modifier matches.  The selector is a
121           string or (preferred) a regular expression. Later modifiers with
122           the same name overrule earlier definitions.  You may also specify
123           an ARRAY of modifiers per "print".
124
125           See section "Interpolation: Modifiers" about the details.
126
127       $obj->encodeFor(HASH|undef|($predefined, %overrule))
128           [0.91] Enable/define the output encoding.  Read section "Output
129           encoding" about the details.
130
131       Printing
132
133       The following are provided as method and as function.  You find their
134       explanation further down on this page.
135
136       $obj->printi([$fh], $format, PAIRS|HASH);
137
138       $obj->printp([$fh], $format, PAIRS|HASH);
139
140       $obj->sprinti($format, PAIRS|HASH);
141
142       $obj->sprintp($format, LIST, PAIRS);
143

FUNCTIONS

145       The functional interface creates a hidden object.  You may import any
146       of these functions explicitly, or all together by not specifying the
147       names.
148
149       . Example
150
151         use String::Print;           # all
152         use String::Print 'sprinti'; # only sprinti
153
154         use String::Print 'printi'   # only printi
155           , modifiers   => [ EUR   => sub {sprintf "%5.2f e", $_[0]} ]
156           , serializers => [ UNDEF => sub {'-'} ];
157
158         printi "price: {p EUR}", p => 3.1415; # price: ␣␣3.14 e
159         printi "count: {c}", c => undef;      # count: -
160
161       printi( [$fh], $format, PAIRS|HASH )
162           Calls sprinti() to fill the data in PAIRS or HASH in $format, and
163           then sends it to the $fh (by default the selected file)
164
165             open my $fh, '>', $file;
166             printi $fh, ...
167
168             printi \*STDERR, ...
169
170       printp( [$fh], $format, PAIRS|HASH )
171           Calls sprintp() to fill the data in PAIRS or HASH in $format, and
172           then sends it to the $fh (by default the selected file)
173
174       sprinti($format, PAIRS|HASH|OBJECT)
175           The $format refers to some string, maybe the result of a
176           translation.
177
178           The PAIRS (which may be passed as LIST, HASH, or blessed HASH)
179           contains a mixture of special and normal variables to be filled in.
180           The names of the special variables (the options) start with an
181           underscore ("_").
182
183            -Option  --Default
184             _append   undef
185             _count    undef
186             _join     ', '
187             _prepend  undef
188
189           _append => STRING|OBJECT
190             Text as STRING appended after $format, without interpolation.
191
192           _count => INTEGER
193             Result of the translation process: when Log::Report subroutine
194             __xn is are used for count-sensitive translation.  Those function
195             may add more specials to the parameter list.
196
197           _join => STRING
198             Which STRING to use when an ARRAY is being filled-in as
199             parameter.
200
201           _prepend => STRING|OBJECT
202             Text as STRING prepended before $format, without interpolation.
203             This may also be an OBJECT which gets stringified, but variables
204             not filled-in.
205
206       sprintp($format, LIST, PAIRS)
207           Where sprinti() uses named parameters --especially useful when the
208           strings need translation-- this function stays close to the
209           standard "sprintf()".  All features of POSIX formats are supported.
210           This should say enough: you can use "%3$0#5.*d", if you like.
211
212           It may be useful to know that the positional $format is rewritten
213           and then fed into sprinti().  Be careful with the length of the
214           LIST: superfluous parameter PAIRS are passed along to "sprinti()",
215           and should only contain "specials": parameter names which start
216           with '_'.
217
218           example: of the rewrite
219
220             # positional parameters
221             my $x = sprintp "dumpfiles: %s\n", \@dumpfiles
222                , _join => ':';
223
224             # is rewritten into, and then processed as
225             my $x = sprinti "dumpfiles: {_1}\n"
226                , _1 => \@dumpfiles, _join => ':';
227

DETAILS

229   Why use "printi()", not "printf()"?
230       The "printf()" function is provided by Perl's CORE; you do not need to
231       install any module to use it.  Why would you use consider using this
232       module?
233
234       translating
235           "printf()" uses positional parameters, where printi() uses names to
236           refer to the values to be filled-in.  Especially in a set-up with
237           translations, where the format strings get extracted into PO-files,
238           it is much clearer to use names.  This is also a disadvantage of
239           printp()
240
241       pluggable serializers
242           "printi()" supports serialization for specific data-types: how to
243           interpolate "undef", HASHes, etc.
244
245       pluggable modifiers
246           Especially useful in context of translations, the FORMAT string may
247           contain (language specific) helpers to insert the values correctly.
248
249       correct use of utf8
250           Sized string formatting in "printf()" is broken: it takes your
251           string as bytes, not Perl strings (which may be utf8).  In unicode,
252           one "character" may use many bytes.  Also, some characters are
253           displayed double wide, for instance in Chinese.  The printi()
254           implementation will use Unicode::GCString for correct behavior.
255
256       automatic output encoding (for HTML)
257           You can globally declare that all produced strings must be encoded
258           in a certain format, for instance that HTML entities should be
259           encoded.
260
261   Four components
262       To fill-in a FORMAT, four clearly separated components play a role:
263
264       1. modifiers
265           How to change the provided values, for instance to hide locale
266           differences.
267
268       2. serializer
269           How to represent (the modified) the values correctly, for instance
270           "undef" and ARRAYs.
271
272       3. conversion
273           The standard UNIX format rules, like %d.  One conversion rule has
274           been added 'S', which provides unicode correct behavior.
275
276       4. encoding
277           Prepare the output for a certain syntax, like HTML.
278
279       Simplified:
280
281         # sprinti() replaces "{$key$modifiers$conversion}" by
282         $encode->($format->($serializer->($modifiers->($args{$key}))))
283
284         # sprintp() replaces "%pos{$modifiers}$conversion" by
285         $encode->($format->($serializer->($modifiers->($arg[$pos]))))
286
287       Example:
288
289         #XXX Your manual-page reader may not support the unicode used
290         #XXX in the examples below.
291         printi "price: {price € %-10s}", price => $cost;
292         printi "price: {price € %-10s}", { price => $cost };
293         printp "price: %-10{€}s", $cost;
294
295         $value      = $cost (in €)
296         $modifier   = convert € to local currency £
297         $serializer = show float as string
298         $format     = column width %-10s
299         $encode     = £ into &pound;     # when encodingFor('HTML')
300
301   Interpolation: keys
302       A key is a bareword (like a variable name) or a list of barewords
303       separated by dots (no blanks!)
304
305       Please use explanatory key names, to help the translation process once
306       you need that (in the future).
307
308       Simple keys
309
310       A simple key directly refers to a named parameter of the function or
311       method:
312
313         printi "Username: {name}", name => 'John';
314
315       You may also pass them as HASH or CODE:
316
317         printi "Username: {name}", { name => 'John' };
318         printi "Username: {name}", name => sub { 'John' };
319         printi "Username: {name}", { name => sub { 'John' } };
320         printi "Username: {name}", name => sub { sub {'John'} };
321
322       The smartness of pre-processing CODE is part of serialization.
323
324       Complex keys
325
326       [0.91] In the previous section, we kept our addressing it simple: let's
327       change that now.  Two alternatives for the same:
328
329         my $user = { name => 'John' };
330         printi "Username: {name}", name => $user->{name}; # simple key
331         printi "Username: {user.name}", user => $user;    # complex key
332
333       The way these complex keys work, is close to the flexibility of
334       template toolkit: the only thing you cannot do, is passing parameters
335       to called CODE.
336
337       You can pass a parameter name as HASH, which contains values.  This may
338       even be nested into multiple levels.  You may also pass objects, class
339       (package names), and code references.
340
341       In above case of "user.name", when "user" is a HASH it will take the
342       value which belongs to the key "name".  When "user" is a CODE, it will
343       run code to get a value.  When "user" is an object, the method "name"
344       is called to get a value back.  When "user" is a class name, the "name"
345       refers to an instance method on that class.
346
347       More examples which do work:
348
349         # when name is a column in the database query result
350         printi "Username: {user.name}", user => $sth->fetchrow_hashref;
351
352         # call a sub which does the database query, returning a HASH
353         printi "Username: {user.name}", user => sub { $db->getUser('John') };
354
355         # using an instance method (object)
356         { package User;
357           sub new  { bless { myname => $_[1] }, $_[0] }
358           sub name { $_[0]->{myname} }
359         }
360         my $user = User->new('John');
361         printi "Username: {user.name}", user => $user;
362
363         # using a class method
364         sub User::count   { 42 }
365         printi "Username: {user.count}", user => 'User';
366
367         # nesting, mixing
368         printi "Complain to {product.factory.address}", product => $p;
369
370         # mixed, here CODE, HASH, and Object
371         printi "Username: {document.author.name}", document => sub {
372           return +{ author => User->new('John') }
373         };
374
375       Limitation: you cannot pass arguments to CODE calls.
376
377   Interpolation: Serialization
378       The 'interpolation' functions have named VARIABLES to be filled-in, but
379       also additional OPTIONS.  To distinguish between the OPTIONS and
380       VARIABLES (both a list of key-value pairs), the keys of the OPTIONS
381       start with an underscore "_".  As result of this, please avoid the use
382       of keys which start with an underscore in variable names.  On the other
383       hand, you are allowed to interpolate OPTION values in your strings.
384
385       There is no way of checking beforehand whether you have provided all
386       values to be interpolated in the translated string.  When you refer to
387       value which is missing, it will be interpreted as "undef".
388
389       strings
390           Simple scalar values are interpolated "as is"
391
392       CODE
393           When a value is passed as CODE reference, that function will get
394           called to return the value to be filled in.  For interpolating, the
395           following rules apply:
396
397       SCALAR
398           Takes the value where the scalar reference points to.
399
400       ARRAY
401           All members will be interpolated with ",␣" between the elements.
402           Alternatively (maybe nicer), you can pass an interpolation
403           parameter via the "_join" OPTION.
404
405             printi "matching files: {files}", files => \@files, _join => ', '
406
407       HASH
408           By default, HASHes are interpolated with sorted keys,
409
410              $key => $value, $key2 => $value2, ...
411
412           There is no quoting on the keys or values (yet).  Usually, this
413           will produce an ugly result anyway.
414
415       Objects
416           With the "serialization" parameter, you can overrule the
417           interpolation of above defaults, but also add rules for your own
418           objects.  By default, objects get stringified.
419
420             serialization => [ $myclass => \&name_in_reverse ]
421
422             sub name_in_reverse($$$)
423             {   my ($formatter, $object, $args) = @_;
424                 # the $args are all parameters to be filled-in
425                 scalar reverse $object->name;
426             }
427
428   Interpolation: Modifiers
429       Modifiers are used to change the value to be inserted, before the
430       characters get interpolated in the line.  This is a powerful
431       simplification.  Let's discuss this with an example.
432
433       In traditional (gnu) gettext, you would write:
434
435         printf(gettext("approx pi: %.6f\n"), PI);
436
437       to get PI printed with six digits in the fragment.  Locale::TextDomain
438       has two ways to achieve that:
439
440         printf __"approx pi: %.6f\n", PI;
441         print __x"approx pi: {approx}\n", approx => sprintf("%.6f", PI);
442
443       The first does not respect the wish to be able to reorder the arguments
444       during translation (although there are ways to work around that)  The
445       second version is quite long.  The string to be translated differs
446       between the two examples.
447
448       With "Log::Report", above syntaxes do work as well, but you can also
449       do:
450
451         # with optional translations
452         print __x"approx pi: {pi%.6f}\n", pi => PI;
453
454       The base for "__x()" is the printi() provided by this module.
455       Internally, it will call "printi" to fill-in parameters:
456
457         printi "approx pi: {pi%.6f}\n", pi => PI;
458
459       Another example:
460
461         printi "{perms} {links%2d} {user%-8s} {size%10d} {fn}\n",
462            perms => '-rw-r--r--', links => 7, user => 'me',
463            size => 12345, fn => $filename;
464
465       An additional advantage (when you use translation) is the fact that not
466       all languages produce comparable length strings.  Now, the translators
467       can change the format, such that the layout of tables is optimal for
468       their language.
469
470       Above example in printp() syntax, shorter but less maintainable:
471
472         printp "%s %2d %-8s 10d %s\n",
473            '-rw-r--r--', 7, 'me', 12345, $filename;
474
475   Interpolation: default modifiers
476       Default modifier: POSIX format
477
478       As shown in the examples above, you can specify a format.  This can,
479       for instance, help you with rounding or columns:
480
481         printp "π = {pi%.3f}", pi => 3.1415;
482         printp "weight is {kilogram%d}", kilogram => 127*OUNCE_PER_KILO;
483         printp "{filename%-20.20s}\n", filename => $fn;
484
485       - improvements on POSIX format
486
487       The POSIX "printf()" does not handle unicode strings.  Perl does
488       understand that the 's' modifier may need to insert utf8 so does not
489       count bytes but characters.  "printi()" does not use characters but
490       "grapheme clusters" via Unicode::GCString.  Now, also composed
491       characters do work correctly.
492
493       Additionally, you can use the new 'S' conversion to count in columns.
494       In fixed-width fonts, graphemes can have width 0, 1 or 2.  For
495       instance, Chinese characters have width 2.  When printing in fixed-
496       width, this 'S' is probably the better choice over 's'.  When the field
497       does not specify its width, then there is no performance penalty for
498       using 'S'.
499
500         # name right aligned, commas on same position, always
501         printp "name: {name%20S},\n", name => $some_chinese;
502
503       Default modifier: BYTES
504
505       [0.91] Too often, you have to translate a (file) size into humanly
506       readible format.  The "BYTES" modifier simplifies this a lot:
507
508         printp "{size BYTES} {fn}\n", fn => $fn, size => -s $fn;
509
510       The output will always be 6 characters.  Examples are "999  B", "1.2
511       kB", and " 27 MB".
512
513       Default modifiers: YEAR, DATE, TIME, DT, and DT()
514
515       [0.91] A set of modifiers help displaying dates and times.  They are a
516       little flexible in values they accept, but do not expect miracles: when
517       it get harder, you will need to process it yourself.
518
519       The actual treatment of a time value depends on the value: three
520       different situations:
521
522       1. numeric
523           A pure numeric value is considered "seconds since epoch", unless it
524           is smaller than 21000000, in which case it is taken as date without
525           separators.
526
527       2. date format without time-zone
528           The same formats are understood as in the next option, but without
529           time-zone information.  The date is processed as text as if in the
530           local time zone, and the output in the local time-zone.
531
532       3. date format with time-zone
533           By far not all possible date formats are supported, just a few
534           common versions, like
535
536             2017-06-27 10:04:15 +02:00
537             2017-06-27 17:34:28.571491+02  # psql timestamp with zone
538             20170627100415+2
539             2017-06-27T10:04:15Z           # iso 8601
540             20170627                       # only for YEAR and DATE
541             2017-6-1                       # only for YEAR and DATE
542             12:34                          # only for TIME
543
544           The meaning of 05-04-2017 is unclear, so not supported.
545           Milliseconds get ignored.
546
547           When the provided value has a timezone indication, it will get
548           converted into the local timezone of the observer.
549
550       The output of "YEAR" is in format 'YYYY', for "DATE" it will always be
551       'YYYY-MM-DD', where "TIME" produces 'HH:mm:ss'.
552
553       The short form "DT" is an alias for "DT(FT)".  The DT modifier can
554       produce different formats:
555
556         DT(ASC)     : %a %b %e %T %Y       asctime output
557         DT(FT)      : %F %T                YYYY-MM-DD HH:mm:ss
558         DT(ISO)     : %FT%T%z              iso8601
559         DT(RFC822)  : %a, %d %b %y %T %z   email old
560         DT(RFC2822) : %a, %d %b %Y %T %z   email newer
561
562       You may suggest additional formats, or add your own modifier.
563
564       Default modifiers: //word, //"string", //'string'
565
566       [0.91] By default, an undefined value is shown as text 'undef'.  Empty
567       strings are shown as nothing.  This may not be nice.  You may want to
568       be more specific when a value is missing.
569
570          "visitors: {count //0}"
571          "published: {date DT//'not yet'}"
572          "copyright: {year//2017 YEAR}
573
574       Modifiers will usually return "undef" when they are called with an
575       undefined or empty value.  By the right order of '//', you may product
576       different kinds of output:
577
578          "price: {price//5 EUR}"
579          "price: {price EUR//unknown}"
580
581       Private modifiers
582
583       You may pass your own modifiers.  A modifier consists of a selector and
584       a CODE, which is called when the selector matches.  The selector is
585       either a string or a regular expression.
586
587         # in Object Oriented syntax:
588         my $f = String::Print->new
589           ( modifiers => [ qr/[€₤]/ => \&money ]
590           );
591
592         # in function syntax:
593         use String::Print 'printi', 'sprinti'
594           , modifiers => [ qr/[€₤]/ => \&money ];
595
596         # the implementation:
597         sub money$$$$)
598         { my ($formatter, $modif, $value, $args) = @_;
599
600             $modif eq '€' ? sprintf("%.2f EUR", $value+0.0001)
601           : $modif eq '₤' ? sprintf("%.2f GBP", $value/1.16+0.0001)
602           :                 'ERROR';
603         }
604
605       Using printp() makes it a little shorter, but will become quite complex
606       when there are more parameter in one string.
607
608         printi "price: {p€}", p => $pi;   # price: 3.14 EUR
609         printi "price: {p₤}", p => $pi;   # price: 2.71 GBP
610
611         printp "price: %{€}s", $pi;       # price: 3.14 EUR
612         printp "price: %{₤}s", $pi;       # price: 2.71 GBP
613
614       This is very useful in the translation context, where the translator
615       can specify abstract formatting rules.  As example, see the (GNU)
616       gettext files, in the translation table for Dutch into English.  The
617       translator tells us which currency to use in the display.
618
619         msgid  "kostprijs: {p€}"
620         msgstr "price: {p₤}"
621
622       Another example.  Now, we want to add timestamps.  In this case, we
623       decide for modifier names in "\w", so we need a blank to separate the
624       parameter from the modifer.
625
626       Modifiers: stacking
627
628       You can add more than one modifier.  The modifiers detect the extend of
629       their own information (via a regular expression), and therefore the
630       formatter understands where one ends and the next begins.
631
632       The modifiers are called in order:
633
634         printi "price: {p€%9s}\n", p => $p; # price: ␣␣␣123.45
635         printi ">{t T%10s}<", t => $now;    # >␣␣12:59:17<
636
637         printp "price: %9{€}s\n", $p;       # price: ␣␣␣123.45
638         printp ">%10{T}s<", $now;           # >␣␣12:59:17<
639
640   Output encoding
641       [0.91] This module is also used by Log::Report::Template, which is used
642       to insert (translated) strings with parameters into HTML templates.
643       You can imagine that some of the parameter may need to be encoded to
644       HTML in the template, and other not.
645
646       example with Log::Report::Template
647
648       In pure Template Toolkit, you would write
649
650         # in your TT-template
651         <div>Username: [% username | html %]</div>
652         # in your code
653         username => $user->name,
654
655       With plain String::Print with output encoding enabled, you can do:
656
657         # in your TT-template
658         <div>[% show_username %]</div>
659         # in your code with encodeFor('HTML')
660         show_username => printi("Username: {user}", user => $user->name),
661         # or
662         show_username => printp("Username: %s", $user->name),
663
664       That does not look very efficient, however it changes for the good when
665       this is combined with Log::Report::Lexicon (translations)  You can
666       either do:
667
668         # in your TT-template
669         <div>[% show_username %]</div>
670         # in your code with encodeFor('HTML')
671         show_username => __x("Username: {user}", user => $user->name),
672
673       Shorter:
674
675         # in your TT-template with encodeFor('HTML')
676         <div>[% loc("Username: {user}", user => username) %]</div>
677         # in your code
678         username => $user->name,
679
680       Even shorter:
681
682         # in your TT-template with encodeFor('HTML')
683         <div>[% loc("Username: {user.name}", user => userobj) %]</div>
684         # in your code
685         userobj => $user,
686
687       Shortest:
688
689         # in your TT-template with encodeFor('HTML')
690         <div>[% loc("Username: {user.name}") %]</div>
691         # in your code
692         user => $user,
693
694       Shorter that the original, and translations for free!  More examples in
695       Log::Report::Template.
696
697       Output encoding exclusion
698
699       In some cases, the data which is inserted is already encoded in the
700       output syntax.  For instance, you already have HTML to be included.
701
702       The default exclusion rule for HTML output is "qr/html$/i", which means
703       that all inserted named parameters, where the name ends on "html" will
704       not get html-entity encoded.
705
706       This will work by default:
707
708         # with encodeFor('HTML')
709         printp "Me & Co: {name}, {description_html}",
710            name => 'René', description_html => $descr;
711
712       This may result in:
713
714         Me &amp; Co: Ren&eacute;, <font color="red">new member</font>
715
716       Better not to have HTML in your program: leave it to the template.  But
717       in some cases, you have no choice.
718
719   Compared to other modules on CPAN
720       There are a quite a number of modules on CPAN which extend the
721       functionality of "printf()".  To name a few: String::Format
722       <http://search.cpan.org/~darren/String-Format>, String::Errf
723       <http://http://search.cpan.org/~rjbs/String-Errf>, String::Formatter
724       <http://http://search.cpan.org/~rjbs/String-Formatter>,
725       Text::Sprintf::Named <http://search.cpan.org/~shlomif/Text-Sprintf-
726       Named>, Acme::StringFormat <http://search.cpan.org/~gfuji/Acme-
727       StringFormat>, Text::sprintf <http://search.cpan.org/~sharyanto/Text-
728       sprintfn>, Log::Sprintf <http://search.cpan.org/~frew/Log-Sprintf>, and
729       String::Sprintf <http://search.cpan.org/~bartl/String-Sprintf>.  They
730       are all slightly different.
731
732       When the "String::Print" module was created, none of the modules
733       mentioned above handled unicode correctly.  Global configuration of
734       serializers and modifiers is also usually not possible, sometimes
735       provided per explicit function call.  Only "String::Print" cleanly
736       separates the roles of serializers, modifiers, and conversions.
737
738       "String::Print" is nicely integrated with Log::Report.
739

SEE ALSO

741       This module is part of String-Print distribution version 0.93, built on
742       January 23, 2018. Website: http://perl.overmeer.net/CPAN/
743

LICENSE

745       Copyrights 2016-2018 by [Mark Overmeer]. For other contributors see
746       ChangeLog.
747
748       This program is free software; you can redistribute it and/or modify it
749       under the same terms as Perl itself.  See http://dev.perl.org/licenses/
750
751
752
753perl v5.30.0                      2019-07-26                  String::Print(3)
Impressum