package Text::Sprintf::Named; use warnings; use strict; use Carp; use warnings::register; =head1 NAME Text::Sprintf::Named - sprintf-like function with named conversions =head1 VERSION Version 0.0301 =cut our $VERSION = '0.0301'; =head1 SYNOPSIS use Text::Sprintf::Named; my $formatter = Text::Sprintf::Named->new( {fmt => "Hello %(name)s! Today is %(day)s!"} ); # Returns "Hello Ayeleth! Today is Sunday!" $formatter->format({args => {'name' => "Ayeleth", 'day' => "Sunday"}}); # Returns "Hello John! Today is Thursday!" $formatter->format({args => {'name' => "John", 'day' => "Thursday"}}); =head1 DESCRIPTION Text::Sprintf::Named provides a sprintf equivalent with named conversions. Named conversions are sprintf field specifiers (like C<"%s"> or C<"%4d>") only they are associated with the key of an associative array of parameters. So for example C<"%(name)s"> will emit the C<'name'> parameter as a string, and C<"%(num)4d"> will emit the C<'num'> parameter as a variable with a width of 4. =head1 FUNCTIONS =head2 my $formatter = Text::Sprintf::Named->new({fmt => $format}) Creates a new object which formats according to the C<$format> format. =cut sub new { my $class = shift; my $self = {}; bless $self, $class; $self->_init(@_); return $self; } sub _init { my ($self, $args) = @_; my $fmt = $args->{fmt} or confess "The 'fmt format was not specified for Text::Sprintf::Named."; $self->_fmt($fmt); return 0; } sub _fmt { my $self = shift; if (@_) { $self->{_fmt} = shift; } return $self->{_fmt}; } =head2 $formatter->format({args => \%bindings}) Returns the formatting string as formatted using the named parameters pointed to by the C<args> parameter. =cut sub format { my $self = shift; my $args = shift || {}; if ( (scalar keys %{$args}) > 0 && not exists $args->{args} ){ warnings::warnif( $self, 'Format parameters were specified, but none of them were \'args\', this is probably a mistake.' ); } my $named_params = $args->{args} || {}; my $format = $self->_fmt; $format =~ s/%(%|\(([a-zA-Z_]\w*)\)([\+\-\.\d]*)([DEFGOUXbcdefgiopsux]))/ $self->_conversion({ format_args => $args, named_params => $named_params, conv => $1, name => $2, conv_prefix => $3, conv_letter => $4, }) /ge; return $format; } =head2 $self->calc_param({%args}) This method is used to calculate the parameter for the conversion. It can be over-rided by subclasses so it will behave differently. An example can be found in C<t/02-override-param-retrieval.t> where it is used to call the accessors of an object for values. %args contains: =over 4 =item * named_params The named paramters. =item * name The name of the conversion. =back =cut sub calc_param { my ($self, $args) = @_; if ( not exists $args->{named_params}->{$args->{name}} ){ warnings::warnif($self, "Token '$args->{name}' specified in the format '$self->{_fmt}' was not found." ); return ''; } return $args->{named_params}->{$args->{name}}; } sub _conversion { my ($self, $args) = @_; if ($args->{conv} eq "%") { return "%"; } else { return $self->_sprintf( ("%" . $args->{conv_prefix} . $args->{conv_letter}), $self->calc_param($args), ); } } sub _sprintf { my ($self, $format, @args) = @_; return sprintf($format, @args); } =head1 AUTHOR Shlomi Fish, C<< shlomif@cpan.org >> , L<http://www.shlomifish.org/> =head1 BUGS Please report any bugs or feature requests to C<bug-text-sprintf-named at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Text::Sprintf::Named>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc Text::Sprintf::Named You can also look for information at: =over 4 =item * AnnoCPAN: Annotated CPAN documentation L<http://annocpan.org/dist/Text::Sprintf::Named> =item * CPAN Ratings L<http://cpanratings.perl.org/d/Text::Sprintf::Named> =item * RT: CPAN's request tracker L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text::Sprintf::Named> =item * Search CPAN L<http://search.cpan.org/dist/Text::Sprintf::Named> =item * Subversion Repository L<http://svn.berlios.de/svnroot/repos/web-cpan/Text-Sprintf/trunk/> =back =head1 ACKNOWLEDGEMENTS The (possibly ad-hoc) regex for matching the optional digits+symbols parameters' prefix of the sprintf conversion was originally written by Bart Lateur (BARTL on CPAN) for his L<String::Sprintf> module. =head1 COPYRIGHT & LICENSE Copyright 2006 Shlomi Fish, all rights reserved. This program is released under the following license: MIT/X11: L<http://www.opensource.org/licenses/mit-license.php> =cut 1; # End of Text::Sprintf::Named