Home » Howtos » Using perl » Length |
Quite often you will want to know the length or size of a variable. It may be a scalar variable, or you may want to know how many elements are in an array or a hash.
Size, or length, can mean a different thing depending on what context you mean. Generally it can mean the number of characters in a string, or the number of elements in an array or hash. However, if you are using Unicode characters the number of characters in a string may be different to the number of bytes in the string.
To determine the number of characters in an expression use the length()
function:
#!/usr/bin/perl use strict; use warnings; my $name = 'Bob'; my $size = length($name); print "$size\n"; exit 0;
This example prints the number of characters in the string $name
:
3
Sometimes you want to know the number of bytes in the string, not the number of characters. This won't affect you for ASCII characters but it may if you are using Unicode characters.
By default the length()
function returns the number of characters. You can tell it to return the number of bytes by specifying use bytes;
, as in this example:
#!/usr/bin/perl use strict; use warnings; my $char = "\x{263a}"; # A smiley face # Put 'use bytes' in a closure so that it doesn't # affect the rest of the program. (The 'use bytes' pragma # disables character semantics for the rest of the lexical # scope in which it appears). { use bytes; my $byte_size = length($char); print "Bytes: $byte_size\n"; } # Character size here my $size = length($char); print "Chars: $size\n"; exit 0;
This outputs:
Bytes: 3 Chars: 1
In Perl you can determine the subscript of the last element of an array and add 1 to it to get the number of elements in the array.
#!/usr/bin/perl use strict; use warnings; my @planets = qw(mercury venus earth mars jupiter); my $size = $#planets + 1; print "$size\n"; exit 0;
This gives us:
5
If you use an array in scalar context, it will return the number of elements in the array:
#!/usr/bin/perl use strict; use warnings; my @planets = qw(mercury venus earth mars jupiter); my $size = @planets; print "$size\n"; exit 0;
This gives us:
5
Apart from being confusing to read, this method can lead to some easy mistakes. For example, consider the following program:
#!/usr/bin/perl use strict; use warnings; my @planets = qw(mercury venus earth mars jupiter); print "@planets\n"; exit 0;
What would you expect it to print?
mercury venus earth mars jupiter
Many functions, double-quotes included, treat arrays differently to scalar variables. The double-quotes cause Perl to flatten the array by concatenating the values into a string.
If you want the number of elements in the array it is best to be explicit about it (see example 6 below).
If you try to use the length()
function on an array, it won't give you the answer you are after:
#!/usr/bin/perl use strict; use warnings; my @planets = qw(mercury venus earth mars jupiter); my $size = length(@planets); print "$size\n"; exit 0;
The output is not what you would expect:
1
This is because the length()
function expects a scalar, so the array is forced into scalar context.
As we saw above (example 4), an array in scalar context already gives us the length. The example above is giving us the length of the length: the length of 5 is 1.
While example 3 and 4 are correct, they aren't very readable or friendly to use. Perl has the scalar()
function which forces the array into scalar context, giving you the length:
#!/usr/bin/perl use strict; use warnings; my @planets = qw(mercury venus earth mars jupiter); my $size = scalar(@planets); print "$size\n"; exit 0;
This also gives us the correct answer:
5
Sometimes you will also want to know the number of elements in a hash. This is easily done using the keys()
function to return the keys as an list, and the scalar()
function to return how many keys there are:
#!/usr/bin/perl use strict; use warnings; my %planet_mass_compared_to_earth = ( mercury => 0.055, venus => 0.86, earth => 1.0, mars => 0.11, jupiter => 318, ); my $size = scalar(keys %planet_mass_compared_to_earth); print "$size\n"; exit 0;
The output of this program is:
5
You can also determine the memory usage in bytes of any variable, including multi-dimensional structures (e.g. a hash of hashes, or an array of arrays, or array of hashes etc). To do this, use the Devel::Size module.
#!/usr/bin/perl use strict; use warnings; use Devel::Size qw(total_size); my %planet_data = ( 1 => { name => 'Mercury', mass_relative_to_earth => 0.055, }, 2 => { name => 'Venus', mass_relative_to_earth => 0.86, }, 3 => { name => 'Earth', mass_relative_to_earth => 1.0, }, 4 => { name => 'Mars', mass_relative_to_earth => 0.11, }, 5 => { name => 'Jupiter', mass_relative_to_earth => 318, }, ); my $total_size = total_size(\%planet_data); print "Total Size: $total_size\n"; exit 0;
On our machine this outputs:
Total Size: Total Size: 1158
This answer is somewhat system dependent. To get a better understanding of how Devel::Size measures the size of variables, see perldoc Devel::Size.
perldoc -f length perldoc -f scalar perldoc bytes perldoc Devel::Size