Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Perl module symbol import versus direct invocation

by robartes (Priest)
on Feb 26, 2003 at 07:40 UTC ( #238688=note: print w/replies, xml ) Need Help??


in reply to Perl module symbol import versus direct invocation

Actually, it does. Calling a function using the -> syntax calls it as an object method. The only practical distinction is that the first argument passed to the function then becomes a reference to the object (it is supplied automatically by Perl as part of the -> magic). This is probably the source of your error (though I can't be sure, not having seen the source of Date::Calc).

Try instanstiating a Date::Calc object before calling Add_Delta_Days with -> .

Update: You seem to be confusing fully qualifying a symbol with object calling syntax. What you want to do when you qualify a symbol with the package name is Date::Calc::Add_Delta_Days.

CU
Robartes-

  • Comment on Re: Perl module symbol import versus direct invocation

Replies are listed 'Best First'.
Re: Re: Perl module symbol import versus direct invocation
by bart (Canon) on Feb 26, 2003 at 08:51 UTC
    Calling a function using the -> syntax calls it as an object method.
    Nope. -> has a double purpose:
    1. Object method call: $obj->meth(@params)
    2. Class method call: Class->meth(@params)
    What the OP did, is applying the latter: invoking a function intended to be used as a function, as a class method. The result is that an extra parameter is unshifted, by perl, in the argument list, @_, before control is passed to it: the Class, which is a string.

    He should try, with a higher chance of success, to call

    Date::Calc::Add_Delta_Days($year,$month,$day, -3);
      So I guess my next logical question is, why have a Class->meth() call at all, if it's not quite an Object call, and it's still not calling the function with the intended arguments? It uses a weak reference to the classname, and is likely to break things for non-OO modules.

      I suppose you could intend for your module to be used that way, but is there a sane way to test for how your module is being used, other than to always check the first parameter to make sure that it's not your classname? Or is this just a matter of "read the documentation before use"?

          --jaybonci
        I agree it's very annoying that on the callee side, i.e. in the sub, it's virtually impossible to distinguish between being called as a function or as a method. Looks at the mess CGI.pm made of it — look into the subs "self_or_default" and "self_or_CGI".

        A reason to have calls as class methods instead of as functions, is the simple fact that now, inheritance works. It doesn't when you call a sub as a function.

        Two rather well known class methods are import, automatically invoked by use — and often inherited :-) from Exporter, and new, a name people often choose for a sub that serves to create a new instance of a class.

        You can use Devel::Caller's called_as_method to determine when a particular subroutine is being called as an object/class method or as a normal subroutine.

        However, in my opinion, mixing function/procedural and OO APIs in the same subroutines is almost always a bad idea :-)

Re: Re: Perl module symbol import versus direct invocation
by dbp (Pilgrim) on Feb 26, 2003 at 07:55 UTC
    Keep in mind that Date::Calc doesn't provide an oo interface. On the other hand, Date::Calc::Object does and it provides some nice overloaded operators for comparing dates.
Re: Re: Perl module symbol import versus direct invocation
by Abigail-II (Bishop) on Feb 26, 2003 at 09:42 UTC
    Actually, it's calling a class method. There's no object involved here. The first argument will be the name of the class, Date::Calc in this case.

    Abigail

      Exactly, this web page can help to make it more clear.
Re: Re: Perl module symbol import versus direct invocation
by JayBonci (Curate) on Feb 26, 2003 at 07:53 UTC
    Okay, but for instance there isn't a new method in the Date::Calc object. Wouldn't it have to auto-instantiate the object before it could call methods on itself? If it's passing a reference, what is it passing a ref to, if no object has been created?
    jaybonci@starlite:~/perl$ perl -MDate::Calc -e 'my $foo = new Date::Ca +lc;' Can't locate auto/Date/Calc/new.al in @INC (@INC contains: /etc/perl / +usr/local/lib/perl/5.8.0 /usr/local/share/perl/5.8.0 /usr/lib/perl5 / +usr/share/perl5 /usr/lib/perl/5.8.0 /usr/share/perl/5.8.0 /usr/local/ +lib/site_perl .) at -e line 1


        --jaybonci
      This is no longer in answer to you initial question, as dbp pointed out that Date::Calc does not provide an object interface, but I got curious as to what happens when you call a method on something that is not an object. Lessee...
      #!/usr/local/bin/perl -w use strict; package Test; print Test->method(); sub method { my $self=shift; return $self; } __END__ Test
      Ah, that's right - you get the package name. I knew this ;).

      So that answers your question: if no object has been created, calling a function with -> results in the function getting the package name as the first argument. This also explains the error in your script: Date::Calc::Add_Delta_Days gets 'Date::Calc' as the year, hence the usage message.

      Update: See bart's post below for some more information on -> syntax.

      CU
      Robartes-

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://238688]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2023-03-22 03:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which type of climate do you prefer to live in?






    Results (60 votes). Check out past polls.

    Notices?