in reply to Sub calling sadness

Update: For the complete story on this question, please see John's answer below. The subtlety is that perl's interpretation of the function/method call depends on whether or not the subroutine is defined when the call is compiled.

The syntax:

ThatPackage::blah $foo
is the method-object calling syntax. For instance, consider:
my $baz = []; bless $baz, "ThatPackage"; ok( blah $baz, 'blah-baz');
This will call ThatPackage::blah with first argument of $baz using object method dispatching. The object is expected to be a blessed reference (which is generally the case) or it can also be a package name. When the method is a fully qualified identifier (like ThatPackage::blah), perl will start looking in that specified package for the subroutine to execute (see the MyCritter example in man perlobj.) However, even in this case the object still must be either a blessed reference or an package name - although perl does not check to see if the package actually 'exists.' Since spaces are not allowed in package names you are getting an error when calling ThatPackage::blah $bar.

By contrast, the syntax: ThatPackage::blah($bar) is simple function calling syntax. In this case the subroutine ThatPackage::blah must be defined or an error will be raised.

When using method-object syntax I would say that verifying that the object at least looks like an object is a useful check to make sure that you're doing what you think you're doing.

Replies are listed 'Best First'.
Re^2: Sub calling sadness
by ikegami (Patriarch) on Mar 08, 2008 at 07:12 UTC

    This will call ThatPackage::blah with first argument of $baz using object dispatching

    "Object dispatching?" No, ThatPackage::blah $foo is not an indirect method call if ThatPackage::blah has been declared as a sub. It's a simple function call.

    If sub blah didn't exist in ThatPackage, then it would be an indirect method call, but $baz would be used as the class name, not as an argument.

      My point is simply that when you use the syntax ThatPackage::blah $foo, perl treats it as a method invocation and expects $foo to look like an 'object' (either a blessed reference or a package name), and this is why the OP is getting the error.

        My point was that's not true except in the unusual case where the function is not known when the statement is compiled.

        What I didn't catch is that it turns out that's the case here. Because require was used instead of use, blah didn't exist when the ok statement was compiled, therefore Perl assumed the OP was trying to do an indirect method call. The solution is to change the require to a use (or wrap it with a BEGIN) or to use parentheses.

        Omitting parens in Perl is dangerous. Prepare to encounter odd problems once in a while when Perl incorrectly guess what you want to do. One specific rule is that parens (or "&") are REQUIRED when the function isn't declared before it's used.

Re^2: Sub calling sadness
by nefigah (Monk) on Mar 08, 2008 at 07:18 UTC
    As a Perl noob, I haven't even opened the Object can of worms yet. I was merely trying to call a function defined in a different file... I suppose that means I have to use the 'function calling syntax' (with the parentheses)--i.e., parentheses there are never optional?
    Thanks!


    I'm a peripheral visionary... I can see into the future, but just way off to the side.