forked from szabgab/perlmaven.com
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathundef-on-perl-arrays-and-hashes.tt
More file actions
234 lines (156 loc) · 4.75 KB
/
undef-on-perl-arrays-and-hashes.tt
File metadata and controls
234 lines (156 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
=title undef on Perl arrays and hashes
=timestamp 2013-03-09T17:09:06
=indexes undef, delete, defined
=status show
=books beginner_book
=author szabgab
=index 1
=archive 1
=feed 1
=comments 1
=social 1
=abstract start
When employing <hl>undef</hl> on scalar variable, you can write it in two ways, and they have the same effect.
When you do it on an array or a hash, it will be different. Let's try to clear up the confusion.
=abstract end
<h2>undef of scalar variables</h2>
Check out these two code snippets:
The first one has <hl>$x = undef;</hl>:
<code lang="perl">
use strict;
use warnings;
my $x = 42;
$x = undef;
print defined $x ? 'DEFINED' : 'NOT';
</code>
and the second one uses <hl>undef $x;</hl>
<code lang="perl">
use strict;
use warnings;
my $x = 42;
undef $x;
print defined $x ? 'DEFINED' : 'NOT';
</code>
Both will print "NOT". <hl>$x = undef</hl> and <hl>undef $x</hl> are exactly the same.
They are also the same as <hl>$x = undef()</hl> and <hl>undef($x)</hl>, just in case
you like parentheses.
<h2>undef on array elements</h2>
Try this script which has <hl>$names[1] = undef;</hl> in it:
<code lang="perl">
use strict;
use warnings;
use Data::Dumper qw(Dumper);
my @names = qw(Foo Bar Baz);
$names[1] = undef;
print Dumper \@names;
</code>
It will print the following:
<code>
$VAR1 = [
'Foo',
undef,
'Baz'
];
</code>
Replacing <hl>$names[2] = undef;</hl> by <hl>undef $names[2];</hl> yields the same result
as those two calls are the same.
<h2>delete on arrays</h2>
<hl>delete $names[2];</hl> is deprecated and likely to be removed in a future version of Perl.
To delete the 3rd element of an array (index 2) use <hl>splice(@names, 2, 1)</hl>.
Then go and read more about <a href="/splice-to-slice-and-dice-arrays-in-perl">splice</a>.
<h2>undef on arrays</h2>
We will try this code now, calling <hl>undef @names;</hl>
<code lang="perl">
use strict;
use warnings;
use Data::Dumper qw(Dumper);
my @names = qw(Foo Bar Baz);
undef @names;
print Dumper \@names;
</code>
<code>
$VAR1 = [];
</code>
The array became empty.
We can replace <hl>undef @names;</hl> by <hl>@names = ();</hl> and we get he same result. An empty array.
On the other hand, if we use <hl>@names = undef;</hl> that will leave the array with a single element which is undef.
<code>
$VAR1 = [
undef
];
</code>
This is <b>NOT what you want</b>!
<h2>undef on hash elements</h2>
The script uses <hl>$h{Foo} = undef;</hl> to set the value of a hash key to be <hl>undef</hl>.
<code lang="perl">
use strict;
use warnings;
use Data::Dumper qw(Dumper);
my %h = (Foo => 123, Bar => 456);
$h{Foo} = undef;
print Dumper \%h;
</code>
Will set the value of Foo in the %h hash to be <hl>undef</hl>:
<code>
$VAR1 = {
'Bar' => 456,
'Foo' => undef
};
</code>
<hl>undef $h{Foo};</hl> would do exactly the same.
<h2>delete a hash element</h2>
Writing <hl>delete $h{Foo};</hl> instead of the call to <hl>undef</hl>
will remove both the key and the value from the hash:
<code>
$VAR1 = {
'Bar' => 456
};
</code>
Putting <hl>delete</hl> on the other side does not make sense at all: <hl>$h{Foo} delete;</hl> is a syntax error.
<h2>undef on a whole hash</h2>
See this <hl>undef %h;</hl> in the following code:
<code lang="perl">
use strict;
use warnings;
use Data::Dumper qw(Dumper);
my %h = (Foo => 123, Bar => 456);
undef %h;
print Dumper \%h;
</code>
<code>
$VAR1 = {};
</code>
Writing <hl>%h = ()</hl> instead of <hl>undef %hl</hl> will also make the hash empty just as above.
On the other hand writing <hl>%h = undef;</hl> is incorrect. It will generate the following output:
<code>
Odd number of elements in hash assignment at files/eg.pl line 7.
Use of uninitialized value in list assignment at files/eg.pl line 7.
$VAR1 = {
'' => undef
};
</code>
It looks a bit odd. What happened here is that the <hl>undef</hl> we typed in was converted to an empty string
generating the <a href="/use-of-uninitialized-value">Use of uninitialized value in list assignment at ...</a> warning.
This became the key in the hash.
Then there was no corresponding value. This generated the <b>Odd number of elements in hash assignment</b> warning, and
an <hl>undef</hl> was assigned to be the value of the empty-string key.
In any case, this is <b>NOT what you want</b>!
As a conclusion let me try to answer to straight forward question:
<h2>How do you reset an array and a hash in Perl?</h2>
<code lang="perl">
@a = ();
%h = ();
</code>
<h2>How do you reset a complete hash or a hash key/value pair?</h2>
Reset complete hash:
<code lang="perl">
%h = ();
</code>
Remove a key/value pair:
<code lang="perl">
delete $h{Foo};
</code>
Remove only the value of a key/value pair:
<code lang="perl">
$h{Foo} = undef;
</code>