A while ago I got an e-mail from one of the readers with the following question:

What is the difference between subname $param and subname($param)?

One seems to work, the other throws an error Can't call method ... on unblessed reference.

In other words: do you have to put parentheses around the parameters of function calls?

Let's look at some things:

require

If we run the following script we will get an error: Can't call method "Storable::freeze" on unblessed reference at ... pointing to the line where we call Storable::freeze $data;.

use strict;
use warnings;

require Storable;

my $data = { a => 42 };
my $frozen = Storable::freeze $data;

If we change the problematic line and put the parameters in parentheses: my $frozen = Storable::freeze($data);, everything works fine.

B::Deparse

Let's try to use B::Deparse again. Once it already helped us with the for loop.

Let's run the first version of the script using perl -MO=Deparse store.pl:

use warnings;
use strict;
require Storable;
my $data = {'a', 42};
my $frozen = $data->Storable::freeze;

and the the second version of the script:

use warnings;
use strict;
require Storable;
my $data = {'a', 42};
my $frozen = Storable::freeze($data);

The second version returned exactly the same code as we had in our file. (Well, except that it replaced the fat-arrow by a comma, but we know they are the same.)

On the other hand, in the first script, the critical part of the code was changed to $data->Storable::freeze;.

Perl thought that we are calling the Storable::freeze method on the $data object. This code would work if the $data was a blessed reference, though it would probably do something different than what we meant.

use

If we replace the require Storable; by use Storable; then both cases work correctly, and in both cases B::Deparse will show the code as being Storable::freeze($data);

eval "use Storable";

If instead of calling use directly we wrap it in an eval statement with a string after it, the problem appears again.

Explanation

use happens at compile time. By the time perl sees the call to Storable::freeze it has already loaded the Storable module.

require and eval "use ..."; happens at run time, so when perl compiles the Storable::freeze $data call, it does not know that there is going to be a Storable::freeze functions. At this point it needs to guess what this code is, and it guesses, incorrectly, that we are using the so-called indirect object notation. It thinks $data is going to be an object and Storable::freeze is a method of this object.

That's why B::Deparse shows this code as $data->Storable::freeze;.

Solution

In order to eliminate the error you need to make sure the functions you use are already defined or loaded before you actually use them. Putting parentheses after the function call eliminates this restriction, and allows you put the function call wherever you want.