String Interpolation

From Erlang Community

(Difference between revisions)
Revision as of 21:46, 18 August 2006 (edit)
Cyberlync (Talk | contribs)

← Previous diff
Current revision (23:22, 6 June 2012) (edit) (undo)
Seryl (Talk | contribs)
m (Fixing mispelling to give the correct impression of how subst works.)
 
(6 intermediate revisions not shown.)
Line 1: Line 1:
== Problem == == 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 " +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 == == 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".
Line 11: Line 15:
</code> </code>
-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: +Although if we only construct this string to then immediately pass it off to a port, we can more efficiently:
<code> <code>
-1> YEAR=2004.+2> BBBB = ["Today's date and time is ", httpd_util:rfc1123_date(), ".\n"].
-2004+["Today's date and time is ", "Fri, 20 Aug 2004 22:03:13 GMT", ".\n"]
-2> MONTH="Aug".+</code>
-"Aug"+-- see the Efficiency Guide for more information about this.
-3> DAY=20.+ 
-20+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:
-4> DAYSTR="Fri".+<code>
-"Fri"+3> io:fwrite("Today's date is ~s, ~s ~w ~w.\n", ["Fri", "Aug", 20, 2004]).
-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.
 +ok
 +4> io_lib:fwrite("Today's date is ~s, ~s ~w ~w.\n", ["Fri", "Aug", 20,
 +2004]). [84, 111, 100, 97, 121, 39, 115, 32, 100, % abbreviated output.
 +97, 116, 101, 32, 105, 115, 32, "Fri", 44,
 +32, "Aug", 32, "20", 32, "2004", 46, 10]
 +5> lists:flatten(v(4)).
 +"Today's date is Fri, Aug 20 2004.\n"
</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.+6> Vars = [{patient,"Mary Becket"}, {diagnosis,"You are an octopus."}],
-8+6> template:subst("E-bloodwork autodoctor: Dear $patient, today's checkup
-7> io:fwrite("~s ~s, ~s ~w ~w\n", +indicated a problem: $diagnosis.\n", Vars). "E-bloodwork autodoctor: Dear
-7> ["Today's date is", DAYSTR, httpd_util:month(MNTH), DAY, YEAR]).+Mary Becket, today's checkup indicated a problem: You are an octopus.\n"
-Today's date is Fri, Aug 20 2004+
</code> </code>
-[[Category:CookBook]]+[[Category:CookBook]][[Category:StringRecipes]]

Current revision

[edit] 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 "

[edit] 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:

3> io:fwrite("Today's date is ~s, ~s ~w ~w.\n", ["Fri", "Aug", 20, 2004]).
Today's date is Fri, Aug 20 2004.
ok
4> io_lib:fwrite("Today's date is ~s, ~s ~w ~w.\n", ["Fri", "Aug", 20, 
2004]). [84, 111, 100, 97, 121, 39, 115, 32, 100,    % abbreviated output.
97, 116, 101, 32, 105, 115, 32, "Fri", 44,
32, "Aug", 32, "20", 32, "2004", 46, 10]
5> lists:flatten(v(4)).
"Today's date is Fri, Aug 20 2004.\n"

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).
6> Vars = [{patient,"Mary Becket"}, {diagnosis,"You are an octopus."}],
6> template:subst("E-bloodwork autodoctor: Dear $patient, today's checkup 
indicated a problem: $diagnosis.\n", Vars). "E-bloodwork autodoctor: Dear 
Mary Becket, today's checkup indicated a problem: You are an octopus.\n"
Erlang/OTP Projects
Personal tools