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:
- Object method call: $obj->meth(@params)
- 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);
| [reply] [d/l] [select] |
|
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
| [reply] |
|
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.
| [reply] |
|
|
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 :-)
| [reply] [d/l] |
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. | [reply] |
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 | [reply] [d/l] |
|
Exactly, this web page can help to make it more clear.
| [reply] |
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
| [reply] [d/l] |
|
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- | [reply] [d/l] |