Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Interpolation(3)      User Contributed Perl Documentation     Interpolation(3)

       Interpolation - Arbitrary string	interpolation semantics	(using tie())

       Version 0.74

       Originaly by Mark-Jason Dominus (
       Since version 0.66 maintained by

	 use Interpolation name	=> \&function, ...;
	 print "la la la la $name{blah blah blah}";

	 # This	is like	doing:
	 $VAR =	&function(blah blah blah);
	 print "la la la la $VAR";

       Beginners always	want to	write this:

	 print "The sum	of three and four is: 3+4";

       And they	want the "3+4" part to be evaluated, so	that it	prints this:

	 The sum of three and four is: 7

       Of course, it's a double-quoted string, so it's not evaluated.  The
       only things that	are evaluated in double-quoted strings are variable

       There are solutions to this, but	most of	them are ugly.	This module is
       less ugly. Well .... this module	IS ugly, but only inside. Your code
       may end up being	nice.

       The module also lets you	define arbitrary interpolation semantics.

       For example, you	can say

	  use Interpolation money => \&commify_with_dollar_sign,
			    E	  => 'eval',
			    placename => 'ucwords',

       And then	you can	write these:

	  print	"3 + 4 = $E{3+4}";
	  # Prints  ``3	+ 4 = 7''

	  $SALARY = 57500;
	  print	"The salary is $money{$SALARY}";
	  # Prints  ``The salary is $57,500.00''

	  $PLACE2 = 'n.y. state';
	  print	"$placename{$PLACE1} is	not near $placename{$PLACE2}";
	  # Prints  ``San Bernadino High School	is not near N.Y. State";

       The arguments to	the "use" call should be name-function pairs.  If the
       pair is "($n, $f)", then	$n will	be the name for	the semantics provided
       by $f.  $f must either be a reference to	a function that	you supply, or
       it can be the name of one of the	built-in formatting functions provided
       by this package.	 "Interpolation" will take over	the %n hash or $n
       scalar in your package, and tie it so that acessing $n{X} calls f(X)
       and yields its return value.

       If for some reason you want to, you can add new semantics at run	time
       by using

	 import	Interpolation name => function,	...

       You can remove them again with

	 unimport Interpolation	'name',	...

       Interpolators created by	the import() or	use statements are always
       PACKAGE variables, not lexicals!	 If you	want a lexical interpolator
       you can create it like this:

	       my %name;
	       tie %name, 'Interpolation', sub { ...
	       my %name;
	       tie %name, 'Interpolation', '$$->$', sub	{ ...

       "Interpolation" provides	a few useful built-in formatting functions;
       you can refer to	these by name in the "use" or "import" line.  They

	       eval		       - Evaluate the argument
	       null		       - Same as eval
	       identity		       - Also the same as eval

	       ucwords	       - Capitalize Input String Like This

	       commify	       - 1428571 => 1,428,571.00

	       reverse	       - reverse string

	       sprintf		       - makes "$S{'%.2f %03d'}{37.5,42}" turn into "37.50 042"
		       use Interpolation S => 'sprintf';
		       print "$S{'%.2f %03d'}{37.5, 42}\n";

	       sprintf1		       - makes "$S{'%.2f %03d',	37.5,42}" turn into "37.50 042".
		       use Interpolation S => 'sprintf1';
		       print "$S{'%.2f %03d', 37.5, 42}\n";

	       sprintfX		       - makes "$S{'%.2f %03d'}{37.5}{42}" turn	into "37.50 042".
		       use Interpolation 'S:$$*->$' => 'sprintfX';
		       print "$S{'%.2f %03d'}{37.5}{42}\n";

	       sqlescape	       - escapes single	quotes for use in SQL queries

	       round		       - rounds	the number
		       use Interpolation round => 'round'; print "The sum is: $round{$sum, 0.01}\n";
		       use Interpolation 'round:$$->$' => 'round'; print "The sum is: $round{$sum}{0.01}\n";

	       htmlescape      - escapes characters special to HTML
	       tagescape       - escapes characters special to HTML plus double	and single quotes
			       qq{<input type=text name=foo value="$tagescape{$value}">}
	       jsescape		       - escapes the text to be	used in	JavaScript
			       qq{<a href="JavaScript:foo( '$jsescape{$value}' )">}
		       (the last three require module HTML::Entities)

       It is posible to	pass multiple (or no) arguments	to your	function.
       There are two alternate syntaxes:


       The first syntax	will pass both arguments in $_[0] joined by $;,	so you
       have to split them:

	   use Interpolation add => sub{@_ = split /$;/o, $_[0]; $_[0] + $_[1]};
	   print "3 + 4	= $add{3,4}\n";

       The other syntax	(used for example by builtin 'sprintf')	requires quite
       some magic, so you probably wouldn't want to be forced to write it
       yourself.  (See the source of this module if you	want to	know how
       strange is the code. )

       The other problem is, that your interpolator might want to return an
       array.  In that case you	would anticipate to get	all the	items joined
       by $", but instead you would get	only the last item. You	have to	join
       the list	yourself:

	   use Interpolation foo => sub	{join $", &bar($_[0])};

       To make your life easier	this module provides a way to specify the
       "type" of the interpolator and then does	the necessary splits, joins or
       magic itself.

       The syntax is:

	   use Interpolation 'name:input->output' => sub { ...

       where the input is a list of '$'s, '@'s and '\@'s and the output	is
       either '$' or '@'.  The '$' means that the parameter/output should be
       left intact, while '@' forces a split/join on the parameter/output.
       Each character in the input list	specifies the type of one brace	in the

       In addition you may add an asterisk to the end of the input type
       specification. This will	allow for an arbitrary long list of
       parameters. Their type will be the last specified.

       In previous version you had to "close" the interpolator call by $;.
       That is you would write something like "xxx
       $foo{par1}{par2}...{parn}{$;} xxx".  While this is still	suported it is
       NOT required anymore.

       The default type	is $->$.

	 'foo:$->$' - pass the argument	to function directly and evaluate it in	scalar context
	 'foo:$->@' - pass the argument	to function directly, evaluate it in list context and join
		      the result by $" (by default space)
	 'foo:@->$' - split the	first parameter	by $; and pass the resulting list to the function,
		      evaluate in scalar context
	 'foo:@->@' - split the	first parameter	by $; and pass the resulting list to the function,
		      evaluate in list context and join
	 'foo:$$->$' - ask for two parameters enclosed in braces
	 'foo:$@->$' - ask for two parameters enclosed in braces and split the second one
		       the list	you get	from the split will be added to	@_ flatlist
	 'foo:$\@->$' -	ask for	two parameters enclosed	in braces and split the	second one
			the list you get from the split	will be	passed as a reference to an array
	 'foo:$*->$   -	ask for	arbitrary number of scalar parameters
	 'foo:->$      - no parameters.	This creates a tied scalar.

	'foo:@->$' => &bar   IS	EQUAL TO   'foo' => sub	{&bar(split /$;/o, $_[0])}
	'foo:$->@' => &bar   IS	EQUAL TO   'foo' => sub	{join $", &bar($_[0])}
	'foo:@->@' => &bar   IS	EQUAL TO   'foo' => sub	{join $", &bar(split /$;/o, $_[0])}
	'foo:\@->$' => &bar  IS	EQUAL TO   'foo' => sub	{&bar([split /$;/o, $_[0] ])}

       The builtin function sprintf could be implemented as:
	   'sprintf:$@->$' => sub {sprintf shift,@_}

       Since version 0.69 it is	possible to assign to interpolators of type
       '$->$', '$->@' and '->$'.  The assigned value will be passed to the
       function	you specified as the last parameter:

	       use Interpolation 'count:->$' =>	sub {if	(@_) {$count = $_[0]} else {$count++}};
	       # print "Current	count is $count\n";
	       use Interpolation 'count:$->$' => sub {
		       if (@_ == 2) {
			       $count{$_[0]} = $_[1]
		       } else {
	       # print "Current	count of A is $count{A}\n";

Cool examples
	     use Interpolation "'" => sub {$_ =	$_[0]; s/'/''/g; "'".$_};
	     $db->Sql("SELECT *	FROM People WHERE LastName = $'{$lastname}'");

	 When passing strings to SQL you have to escape	the apostrophes	(and
	 maybe some other characters) this crazy hack allows you do it quite

	 Instead of "... = '$variable'"	you write "... = $'{$variable}'" et
	 voila ;-) You may of course use this syntax for whatever string
	 escaping you like.

		 use Interpolation 'IF:$*->$' => sub {$_[0] ? $_[1] : $_[2]};
		 use Interpolation '?:$*->$' =>	sub {$_[0] ? $_[1] : $_[2]};
		 print <<"*END*"
		 Blah blah blah
		 There was $count $IF{$count > 1}{jobs}{job}.
		 There was $count $?{$count > 1}{jobs}{job}.
		 There was $count job$?{$count > 1}{s}.

       It's easy to forget that	the index to a $hash{...} is an	arbitrary
       expression, unless it looks like	an identifier.	There are two gotchas

       Trap 1.
	     print "$X{localtime}";

	   Here	the "X"	formatter is used to format the	literal	string
	   "localtime";	the "localtime"	built-in function is not invoked.  If
	   you really want the current time, use one of	these:

	     print "$X{+localtime}";
	     print "$X{localtime()}";

       Trap 2.
	     print "$X{What ho?}";

	   This	won't compile---you get	`search	pattern	not terminated'.  Why?
	   Because Perl	sees the "?" and interprets it as the beginning	of a
	   pattern match operator, similar to "/".  (Ah, you forgot that "?"
	   could be a pattern match delimiter even without a leading "m",
	   didn't you?)	 You really need

	     print "$X{'What ho?'}";

       The rule	is simple: That	thing in the braces that looks like a hash key
       really is a hash	key, and so you	need to	put it in quotes under the
       same circumstances that you need	to put any other hash key in quotes.
       You probably wouldn't expect this to work either:

	 $V = $X{What ho?};

       Originaly, Mark-Jason Dominus (C<>),
       Plover Systems co. Now
       maintained by, C<> .

perl v5.32.1			  2009-09-30		      Interpolation(3)

NAME | SYNOPSIS | DESCRIPTION | DETAILS | ADVANCED | Cool examples | Warnings | Author

Want to link to this manual page? Use this URL:

home | help