Skip to content

Commit e546deb

Browse files
committed
[en] massive wording improvements in "Nginx Variables (01)".
1 parent 285663f commit e546deb

File tree

1 file changed

+44
-37
lines changed

1 file changed

+44
-37
lines changed

en/01-NginxVariables01.tut

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,37 @@ Nginx configuration files are essentially small programs.
77
This language's design
88
is heavily influenced by
99
Perl and Bourne Shell as far as I can see, despite the fact that it might not
10-
be Turing-Complete. This is a distinguishing feature of Nginx, as compared
10+
be Turing-Complete and it is declarative in many places. This is a
11+
distinguishing feature of Nginx, as compared
1112
to the other web servers
1213
like Apache or Lighttpd. Being a programming language, "variables" are
1314
thus a natural part of it (exceptions do exist, of course, as in pure
1415
functional languages like Haskell).
1516

1617
Variables are just containers holding various values in imperative languages
1718
like Perl, Bourne Shell, and C/C++.
18-
And "values" here can be numbers like C<3.14>, strings like
19+
And "values" can be numbers like C<3.14>, strings like
1920
C<hello world>, or even complicated things like references to arrays or
20-
hash tables. For the
21-
Nginx configuration language, however, variables can only hold one single type
22-
of values, that is, strings.
21+
hash tables in those languages. For the
22+
Nginx configuration language, however, variables can hold only one type
23+
of values, that is, strings (there is an interesting exception: the 3rd-party
24+
module L<ngx_array_var> extends Nginx variables to hold arrays, but it is
25+
implemented by encoding a C pointer as a binary string value behind the scene).
2326

2427
== Variable Syntax and Interpolation ==
2528

26-
Let's say our F<nginx.conf> configuration file has the following configuration
27-
line:
29+
Let's say our F<nginx.conf> configuration file has the following line:
2830

2931
:nginx
3032
set $a "hello world";
3133

32-
where we assign a value to the variable C<$a> via the L<ngx_rewrite/set>
34+
We assign a value to the variable C<$a> via the L<ngx_rewrite/set>
3335
configuration directive coming from the standard L<ngx_rewrite> module. In
34-
particular, we assign the string value C<hello world> to it.
36+
particular, we assign the string value C<hello world> to C<$a>.
3537

3638
We can see that the Nginx variable name takes a dollar sign (C<$>) in front of
3739
it. This is required by the language syntax: whenever we want to reference an
38-
Nginx variable in the configuration file, we must add a C<$> prefix. This look
40+
Nginx variable in the configuration file, we must add a C<$> prefix. This looks
3941
very familiar to those Perl and PHP programmers.
4042

4143
Such variable prefix modifiers may discomfort some C<Java> and C<C#>
@@ -49,7 +51,7 @@ string literal:
4951

5052
Here we use the value of the existing Nginx variable C<$a> to construct the
5153
value for the variable C<$b>. So after these two directives complete execution,
52-
the value of C<$a> is C<hello>, and C<$b> C<hello, hello>. This technique is
54+
the value of C<$a> is C<hello>, and C<$b> is C<hello, hello>. This technique is
5355
called "variable interpolation" in the Perl world, which makes ad-hoc string
5456
concatenation operators no longer that necessary. Let's use the same term for
5557
the Nginx world from now on.
@@ -98,22 +100,23 @@ not work at all:
98100
? echo "$";
99101
? }
100102

101-
we will get the following error message while loading this configuration:
103+
We will get the following error message while loading this configuration:
102104

103105
[emerg] invalid variable name in ...
104106

105-
Obviously Nginx is try to parse C<$"> as a variable name. Is there a way to
107+
Obviously Nginx tries to parse C<$"> as a variable name. Is there a way to
106108
escape C<$> in the string literal? The answer is "no" (it is still the case in
107109
the
108110
latest Nginx stable
109111
release C<1.2.7>) and I have been hoping that we could write something like
110112
C<$$> to obtain a literal C<$>.
111113

112114
Luckily, workarounds do exist and here is one proposed by Maxim Dounin: first
113-
we assign to a variable a literal string containing the dollar sign character
115+
we assign to a variable a literal string containing a dollar sign character
114116
via a configuration directive that does I<not> support "variable interpolation"
115117
(remember that not all the directives support "variable interpolation"?), and
116-
then use L<ngx_echo/echo> to print out this variable's value. Here is such an
118+
then reference this variable later wherever we need a dollar sign. Here is such
119+
an
117120
example to demonstrate the idea:
118121

119122
:nginx
@@ -139,22 +142,23 @@ Here we make use of the L<ngx_geo/geo> directive of the standard module
139142
L<ngx_geo> to initialize the
140143
C<$dollar> variable with the string C<"$">, thereafter variable C<$dollar>
141144
can be used
142-
wherever we need a literal dollar sign. This works because the L<ngx_geo/geo>
145+
in places that require a dollar sign. This works because the L<ngx_geo/geo>
143146
directive does not
144147
support "variable interpolation" at all. However, the L<ngx_geo> module
145-
is designed to set a Nginx variable to different values according to the
148+
is originally designed to set a Nginx variable to different values according to
149+
the
146150
remote client
147-
address. In the sample above, we just abuse it to initialize the C<$dollar>
151+
address, and in this example, we just abuse it to initialize the C<$dollar>
148152
variable
149153
with the string C<"$"> unconditionally.
150154

151155
=== Disambiguating Variable Names ===
152156

153-
There is a special case when using "variable interpolation" when the variable
154-
name is followed directly by characters consisting the variable names (like
157+
There is a special case for "variable interpolation", that is, when the variable
158+
name is followed directly by characters allowed in variable names (like
155159
letters, digits, and underscores).
156160
In such cases we can use a special notation to disambiguate the variable name
157-
from the subsequent literal characters:
161+
from the subsequent literal characters, for instance,
158162

159163
:nginx
160164
server {
@@ -171,20 +175,22 @@ If it
171175
were written
172176
directly as C<"$firstworld">, Nginx's "variable interpolation" engine (also
173177
known as the "script engine") would try to access the variable
174-
C<$firstworld> instead of C<$first>. To resolve the ambiguity, curly brackets
178+
C<$firstworld> instead of C<$first>. To resolve the ambiguity here, curly braces
175179
must be used
176-
after the C<$> prefix, as in C<${first}>. Let's test this sample:
180+
around the variable name (excluding the C<$> prefix), as in C<${first}>. Let's
181+
test this sample:
177182

178183
:bash
179184
$ curl 'http://localhost:8080/test
180185
hello world
181186

182-
== Variable Declaration or Creation ==
187+
== Variable Declaration and Creation ==
183188

184189
In languages like C/C++, variables must be declared (or created) before they
185190
can be used so that the compiler can allocate storage and perform type checking
186191
at compile-time. Similarly, Nginx creates all the Nginx variables while loading
187-
the configuration file (or in other words, at "configuration time"), so Nginx
192+
the configuration file (or in other words, at "configuration time"), therefore
193+
Nginx
188194
variables are also required to be declared somehow.
189195

190196
Fortunately the L<ngx_rewrite/set> directive and the L<ngx_geo/geo> directive
@@ -210,18 +216,17 @@ L<ngx_echo/echo>. Nginx will just refuse loading this configuration:
210216
Yes, we cannot even start the server!
211217

212218
Nginx variable creation and assignment happen
213-
at completely phases along the timeline.
219+
at completely different phases along the time-line.
214220
Variable creation only occurs when Nginx loads its configuration. On the other
215221
hand, variable assignment occurs when requests are actually
216-
being handled. This also means that we can never create new Nginx variables at
222+
being served. This also means that we can never create new Nginx variables at
217223
"request time".
218224

219225
== Variable Scope ==
220226

221227
Once an Nginx variable is created, it is visible to the entire configuration,
222-
regardless of the location
223-
it is referenced, even across different virtual server configuration blocks.
224-
Here is
228+
even across different virtual server configuration
229+
blocks, regardless of the places it is declared at. Here is
225230
an example:
226231

227232
:nginx
@@ -262,22 +267,24 @@ is only used in that location. When requesting the C</foo> interface, we always
262267
get an empty value for the C<$foo> variable because that is what we get when
263268
accessing an uninitialized variable.
264269

265-
Another important behavior that we can observe from this example is that even
270+
Another important characteristic that we can observe from this example is that
271+
even
266272
though the scope of Nginx variables is the entire configuration, each request
267-
does have its own version of all those variables. Or in other words, each
268-
request has its own copy of value containers for all variables. Requests do not
273+
does have its own version of all those variables' containers. Requests do not
269274
interfere with each other even if they are referencing a variable with the same
270275
name. This is very much like local variables in C/C++ function bodies. Each
271276
invocation of the C/C++ function does use its own version of those local
272-
variables.
277+
variables (on the stack).
273278

274279
For instance, in this sample, we request C</bar> and the variable C<$foo> gets
275280
the value C<32>, which does not affect the value of C<$foo> in subsequent
276281
requests to C</foo> (it is still uninitialized!), because they correspond to
277282
different value containers.
278283

279-
One of the most common mistakes for Nginx newcomers is to regard Nginx
284+
One common mistake for Nginx newcomers is to regard Nginx
280285
variables as something shared among all the requests. Even though the scope of
281-
Nginx variables go across configuration blocks, it never goes beyond request
282-
boundaries. Essentially here we do have two different kinds of scopes here.
286+
Nginx variable I<names> go across configuration blocks at "configuration time",
287+
its I<value container>'s scope never goes beyond request
288+
boundaries at "request time". Essentially here we do have two different kinds
289+
of scope here.
283290

0 commit comments

Comments
 (0)