Erlang Central

Difference between revisions of "String Interpolation"

From ErlangCentral Wiki

(shortened an example, added an Efficiency Guide ref, added a 'traditional string interpolation' answer)
Line 5:Line 5:
 
== Solution ==
 
== Solution ==
  
Make use of Erlang's generic display procedure and variable argument list. For an easy case (displaying date and time), we can make use of the httpd_util:rfc1123_date function to get a string date, and the built-in concatenation (++) operator to construct the string we want:  
+
Make use of Erlang's generic display procedure and variable argument list. For an easy case (displaying date and time), we can make use of the httpd_util:rfc1123_date/0 function to get a string date, and the built-in concatenation (++) operator to construct the string we want:  
 
<code>
 
<code>
 
1> BBBB = "Today's date and time is " ++ httpd_util:rfc1123_date() ++ ".\n".
 
1> BBBB = "Today's date and time is " ++ httpd_util:rfc1123_date() ++ ".\n".
 
"Today's date and time is Fri, 20 Aug 2004 22:03:13 GMT.\n"
 
"Today's date and time is Fri, 20 Aug 2004 22:03:13 GMT.\n"
 
</code>
 
</code>
 +
 +
Although if we only construct this string to then immediately pass it off to a port, we can more efficiently:
 +
<code>
 +
2> BBBB = ["Today's date and time is ", httpd_util:rfc1123_date(), ".\n"].
 +
["Today's date and time is ", "Fri, 20 Aug 2004 22:03:13 GMT", ".\n"]
 +
</code>
 +
-- see the Efficiency Guide for more information about this.
  
 
Other cases require that you use the generic io_lib formatting functions to create strings with the data you want. For example, we could achive the same result as follows:  
 
Other cases require that you use the generic io_lib formatting functions to create strings with the data you want. For example, we could achive the same result as follows:  
 
<code>
 
<code>
1> YEAR=2004.
+
2> io:fwrite("Today's date is ~s, ~s ~w ~w.\n", ["Fri", "Aug", 20, 2004]).
2004
+
2> MONTH="Aug".
+
"Aug"
+
3> DAY=20.
+
20
+
4> DAYSTR="Fri".
+
"Fri"
+
5> io:fwrite("~s ~s, ~s ~w ~w.\n", ["Today's date is",
+
5>      DAYSTR, MONTH, DAY, YEAR]).
+
 
Today's date is Fri, Aug 20 2004.
 
Today's date is Fri, Aug 20 2004.
 
</code>
 
</code>
  
If we wanted to be fancy, we could also use httpd_util:month function to get the correct month name:  
+
Finally, this unoptimized module offers more traditional string interpolation:
 +
<code>
 +
-module(template).
 +
-export([subst/2]).
 +
 
 +
subst(Fmt,[]) -> lists:flatten(Fmt);
 +
subst(Fmt,[{K,V}|T]) ->
 +
    {ok,Fmt1,_} = regexp:gsub(Fmt,"\\$" ++ atom_to_list(K),[V]),
 +
    subst(Fmt1,T).
 +
</code>
 
<code>
 
<code>
6> MNTH=8.
+
3> Vars = [{patient,"Mary Becket"}, {diagnosis,"You are an octopus."}],
8
+
3> template:subst("E-bloodwork autodoctor: Dear $patient, today's checkup indicated a problem: $diagnosis.\n", Vars).
7> io:fwrite("~s ~s, ~s ~w ~w\n",                                
+
"E-bloodwork autodiagnosis: Dear Mary Becket, today's checkup indicated a problem: You are an octopus.\n"
7> ["Today's date is", DAYSTR, httpd_util:month(MNTH), DAY, YEAR]).
+
Today's date is Fri, Aug 20 2004
+
 
</code>
 
</code>
  
 
[[Category:CookBook]][[Category:StringRecipes]]
 
[[Category:CookBook]][[Category:StringRecipes]]

Revision as of 17:36, 24 September 2006

Problem

You want to create string using a mixture of literals and computed values. For example you want to display the current date is the string "Today's date is "

Solution

Make use of Erlang's generic display procedure and variable argument list. For an easy case (displaying date and time), we can make use of the httpd_util:rfc1123_date/0 function to get a string date, and the built-in concatenation (++) operator to construct the string we want:

1> BBBB = "Today's date and time is " ++ httpd_util:rfc1123_date() ++ ".\n".
"Today's date and time is Fri, 20 Aug 2004 22:03:13 GMT.\n"

Although if we only construct this string to then immediately pass it off to a port, we can more efficiently:

2> BBBB = ["Today's date and time is ", httpd_util:rfc1123_date(), ".\n"].
["Today's date and time is ", "Fri, 20 Aug 2004 22:03:13 GMT", ".\n"]

-- see the Efficiency Guide for more information about this.

Other cases require that you use the generic io_lib formatting functions to create strings with the data you want. For example, we could achive the same result as follows:

2> io:fwrite("Today's date is ~s, ~s ~w ~w.\n", ["Fri", "Aug", 20, 2004]).
Today's date is Fri, Aug 20 2004.

Finally, this unoptimized module offers more traditional string interpolation:

-module(template).
-export([subst/2]).

subst(Fmt,[]) -> lists:flatten(Fmt);
subst(Fmt,[{K,V}|T]) ->
    {ok,Fmt1,_} = regexp:gsub(Fmt,"\\$" ++ atom_to_list(K),[V]),
    subst(Fmt1,T).
3> Vars = [{patient,"Mary Becket"}, {diagnosis,"You are an octopus."}],
3> template:subst("E-bloodwork autodoctor: Dear $patient, today's checkup indicated a problem: $diagnosis.\n", Vars).
"E-bloodwork autodiagnosis: Dear Mary Becket, today's checkup indicated a problem: You are an octopus.\n"