Temporarily remove hash keys or array elements with `delete local`

Perl 5.12 adds a feature that lets you locally delete a hash key or array element (refresh your memory of local with Item 43: Know the difference between my and local. This new feature allows you to temporarily prune a hash or an array: Continue reading “Temporarily remove hash keys or array elements with `delete local`”

Respect the global state of the flip flop operator

Perl’s flip-flop operator, .., (otherwise known as the range operator in scalar context) is a simple way to choose a window on some data. It returns false until its lefthand side is true. Once the lefthand side is true, the flip-flop operator returns true until its righthand side is true. Once the righthand side is true, the flip flop operator returns false. That is, the lefthand side turns it on and the righthand side turns it off. Continue reading “Respect the global state of the flip flop operator”

Know what your the last evaluated expression actually is.

In Perl, a subroutine or other block structure that returns a value gives back the last evaluated expression, but if you’re not careful you might not recognize what that last evaluation actually is. It’s not necessarily the last statement in the block; it’s just the last one that you actually execute. For this Item, forget about the best practice of using explicit returns. You should do that for precisely the reasons you will see here, but you can’t learn about the problem by avoiding it. Continue reading “Know what your the last evaluated expression actually is.”

Know how Perl handles scientific notation in string to number conversions.

A recent question on Stackoverlow asked about the difference between the same floating numbers being stored in scientific notation and written out. Why does 0.76178 come out differently than 7.6178E-01 When Perl stores them, they can come out as slightly different numbers. This is related to the perlfaq answer to Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?, but a bit more involved. You’ll see how to skip the whole mess at the end, but be patient. Continue reading “Know how Perl handles scientific notation in string to number conversions.”

Know what creates a scope

Scopes can be confusing. Perl 5 introduced lexical, or my, variables that are only visible in the scope in which you define them. To properly scope your variables, you need to know what can define a scope and what doesn’t.

You commonly see lexical variables for subroutine arguments, for instance:

sub foo {
    my( $self, @args ) = @_;
    ...;
    }

The variables $self and @args don’t exist outside of that subroutine (ignoring black magic with things such as PadWalker). Lexicals variables have limited effect and no action at a distance, making them invaluable for robust programming. Not only that, but since the lexical variable names only matter in their scope, you don’t have to know about all of the variables that you have already defined to choose variable names in your scope.

Before Perl 5, all variables were package variables (so, global). Perl 5 couldn’t just ignore all of the existing Perl 4 programs, so it ended up supporting both the global package variables and lexical variables. That can make things confusing if you don’t understand the difference.

First, you need to know what makes a scope. Most people can give you at least one answer: a block creates a scope. Blocks show up in the syntax of many of Perl’s commonly used features:

# a subroutine definition block, perhaps anonymous
sub foo { ... }
my $foo = sub { ... };

# blocks for control stuctures
foreach ( @array ) { ... }
while( $condition ) { ... }
if( $condition ) { ... }

# blocks related to functions:
my $result = do { ... };
my @transformed = map { ... } @input;
my @filtered = grep { ... } @input;

# blocks in regular expressions
m/(?{...})/

Sometimes you can create the lexical variable outside of the block even though it’s scoped to the block. You can declare the lexical variable in the the test for while or if (and cousins), or as the control variable you want to use with foreach:

foreach my $index ( 0 .. 5 ) {
	print "index: $index\n";
	}

while( my $line = <DATA> ) {
	print "line: $line";
	}

if( my $foo = 'abc' ) {
	print "foo is $foo\n";
	}

You don’t need a control structure or operator to use a block to define the scope. You can use a bare block to create a scope:

# bare blocks
{
my $cat = 'Buster';
...;
}

Most Perler’s could identify blocks as scope definers, but there’s another scope definer that many people miss. File this away for your job interview trivia: a file is a scope too. You can’t see lexical variables outside of the file in which you define them, even if you don’t explicitly create the scope with a block. It’s as if there is a virtual block around the entire file.

You can use the file scope to create private class variables. The methods you define in the same file can see the private variables, but code in other files, such as subclasses, can’t mess with them:

package Some::Class;

my $private = 0; # only visible in this file

sub some_method {
   ...; # can see $private
   }

If you want other parts of the program to get or set the value in this private variable despite its scope, you can provide accessor methods. This gives you a chance to head off any shenanigans before you allow someone to change the value:

package Some::Class;

my $private = 0;

sub get_private { $private }
sub set_private { $private = $_[1] }

Some people extend the idea of private class variables too far because they think that a package creates a scope. It doesn’t. A package merely defines the default package unless you explicitly specify one. Since lexical variables aren’t connected to packages, they don’t care want the current package is. If you change the package, even if it’s in another block:

package Some::Class;

my $n = 'Can you see me?';

{
package main;
# $n still visible here
}

package Some::Class::Subclass;

# $n still visible

There are some more tricks with scopes and what constitutes a scoped variable, but that’s a matter for a future Item.

Things to remember

  • Lexical variables are only visible in their scope.
  • A block defines a scope.
  • A file defines a scope.
  • A package does not define a scope.

What’s the difference between a list and an array?

I recently updated perlfaq4‘s answer to “What’s the difference between a list and an array?”. The difference between data and variables is often lost of the person who starts their programming career in a high level language.

We hit this subject pretty hard in the first chapter of Effective Perl Programming, 2nd Edition in at least three Items:

  • Item 9: Know the difference between lists and arrays.
  • Item 10: Don’t assign undef when you want an empty array.
  • Item 12: Understand context and how it affects operations.

Here’s the current answer in perlfaq4:


A list is a fixed collection of scalars. An array is a variable that holds a variable collection of scalars. An array can supply its collection for list operations, so list operations also work on arrays:

# slices
( 'dog', 'cat', 'bird' )[2,3];
@animals[2,3];

# iteration
foreach ( qw( dog cat bird ) ) { ... }
foreach ( @animals ) { ... }

my @three = grep { length == 3 } qw( dog cat bird );
my @three = grep { length == 3 } @animals;

# supply an argument list
wash_animals( qw( dog cat bird ) );
wash_animals( @animals );

Array operations, which change the scalars, reaaranges them, or adds or subtracts some scalars, only work on arrays. These can’t work on a list, which is fixed. Array operations include shift, unshift, push, pop, and splice.

An array can also change its length:

$#animals = 1;  # truncate to two elements
$#animals = 10000; # pre-extend to 10,001 elements

You can change an array element, but you can’t change a list element:

$animals[0] = 'Rottweiler';
qw( dog cat bird )[0] = 'Rottweiler'; # syntax error!

foreach ( @animals ) {
	s/^d/fr/;  # works fine
	}

foreach ( qw( dog cat bird ) ) {
	s/^d/fr/;  # Error! Modification of read only value!
	}

However, if the list element is itself a variable, it appears that you can change a list element. However, the list element is the variable, not the data. You’re not changing the list element, but something the list element refers to. The list element itself doesn’t change: it’s still the same variable.

You also have to be careful about context. You can assign an array to a scalar to get the number of elements in the array. This only works for arrays, though:

my $count = @animals;  # only works with arrays

If you try to do the same thing with what you think is a list, you get a quite different result. Although it looks like you have a list on the righthand side, Perl actually sees a bunch of scalars separated by a comma:

my $scalar = ( 'dog', 'cat', 'bird' );  # $scalar gets bird

Since you’re assigning to a scalar, the righthand side is in scalar context. The comma operator (yes, it’s an operator!) in scalar context evaluates its lefthand side, throws away the result, and evaluates it’s righthand side and returns the result. In effect, that list-lookalike assigns to $scalar it’s rightmost value. Many people mess this up becuase they choose a list-lookalike whose last element is also the count they expect:

my $scalar = ( 1, 2, 3 );  # $scalar gets 3, accidentally