Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > XSUB detecting if it was called via Package->method() or Package::method()?

Reply
Thread Tools

XSUB detecting if it was called via Package->method() or Package::method()?

 
 
Chris
Guest
Posts: n/a
 
      11-17-2010
So, if I call
Package->method(),
then the string "Package" will be the first item in @_ when inside the
method() sub.

If I call
$object->method(),
then $ will be the first item in @_ when inside the method() sub.

If I call Package::method(), @_ will be empty.

perldoc perlobj calls the first one a "class method", because it
expects the class name as the first argument, and the second one an
"instance method", because it expects an object reference as the first
argument. The third one I consider a "static method", because it
doesn't expect the first argument to be anything special.

How can an XSUB differentiate between those 3?
 
Reply With Quote
 
 
 
 
Uri Guttman
Guest
Posts: n/a
 
      11-18-2010
>>>>> "C" == Chris <(E-Mail Removed)> writes:

C> So, if I call
Package-> method(),
C> then the string "Package" will be the first item in @_ when inside the
C> method() sub.

C> If I call
C> $object->method(),
C> then $ will be the first item in @_ when inside the method() sub.

C> If I call Package::method(), @_ will be empty.

C> perldoc perlobj calls the first one a "class method", because it
C> expects the class name as the first argument, and the second one an
C> "instance method", because it expects an object reference as the first
C> argument. The third one I consider a "static method", because it
C> doesn't expect the first argument to be anything special.

the third one isn't a method at all. methods are ONLY called with the ->
notation (or by indirect calls which you should avoid). the :: style is
just a fully qualified sub name being called. no different than if you
imported that sub or declared it locally. methods will use inheritence
and the method name can be dynamically created. you can't do that with
sub names without disabling strict. those are some major differences.

C> How can an XSUB differentiate between those 3?

check the first arg type should be easy enough but as with plain perl
you should NEVER allow multiple call styles for a single sub. instance
methods should only be called by objects, class methods via a package
name and plain subs with neither of those. so your problem is solved,
you don't need to know. it is up to the caller to make sure they do what
you document.

uri

--
Uri Guttman ------ http://www.velocityreviews.com/forums/(E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
 
 
 
Chris
Guest
Posts: n/a
 
      11-18-2010

> check the first arg type should be easy enough but as with plain perl
> you should NEVER allow multiple call styles for a single sub.


What if the sub is AUTOLOAD? If I have defined a sub called
Package::AUTOLOAD, then Package->method('foo'), $package-
>method('foo'), and Package::method('foo') will both redirect to the

AUTOLOAD sub. AUTOLOAD then doesn't know if $_[0] is $self, the
string 'Package', or the string 'foo'.
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      11-18-2010
>>>>> "C" == Chris <(E-Mail Removed)> writes:

>> check the first arg type should be easy enough but as with plain perl
>> you should NEVER allow multiple call styles for a single sub.


C> What if the sub is AUTOLOAD? If I have defined a sub called
C> Package::AUTOLOAD, then Package->method('foo'), $package-
>> method('foo'), and Package::method('foo') will both redirect to the

C> AUTOLOAD sub. AUTOLOAD then doesn't know if $_[0] is $self, the
C> string 'Package', or the string 'foo'.

but it knows the NAME of the sub. so it can dispatch based on that. a
sub of a given name should only have one api style. it doesn't matter
how the sub actually gets invoked but how you pass it args.

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
sisyphus
Guest
Posts: n/a
 
      11-18-2010
On Nov 18, 10:43*am, Chris <(E-Mail Removed)> wrote:

> How can an XSUB differentiate between those 3?


########################################
use warnings;
use Math::BigInt;

$x = Math::BigInt->new(100123);


Math::BigInt->foo(42); # class
$x->foo(42); # instance
Math::BigInt::foo(42); # static

package Math::BigInt;

use Inline C => Config =>
BUILD_NOISY=>1;

use Inline C => <<'EOC';

void foo(SV* x, ...) {
dXSARGS;
if(items == 1) printf("static method\n");
else {
if(SvPOK(ST(0))) {
if(strEQ(SvPV_nolen(ST(0)), "Math::BigInt")) printf("class
method\n");
else printf("wtf?\n");
}
else printf("instance method\n");
}
XSRETURN(0);
}

EOC
#########################################

For me, after compiling, it prints:

class method
instance method
static method

Not entirely sure that the logic caters for all possibilities, but you
should get the idea.

When using ellipsis syntax with Inline::C you have to provide at least
one argument - ie foo() must take at least one argument, and that's
why I've provided a (fudge) argument of 42 ... and also why we have to
check for items==1 (not items==0).

In XS, I don't think that stipulation of "at least one arg" applies
(though I don't really know for sure).

Cheers,
Rob
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      11-18-2010
>>>>> "s" == sisyphus <(E-Mail Removed)> writes:

s> Not entirely sure that the logic caters for all possibilities, but you
s> should get the idea.

and if you read my reply, you will see that this is a big mistake. one
sub should not be called with different apis. the whole question is
wrong.

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
Chris
Guest
Posts: n/a
 
      11-18-2010
Let me put this in a little more context.

I'm writing Perl bindings to Qt. So, there's a lot of methods,
including method overloading. So, for instance, in C++ you can write
QApplication app(argc, argv);
QObject::connect( &app, SIGNAL(aboutToQuit()), &app,
SLOT(quit()) );

or you could write
QApplication app(argc, argv);
app.connect( &app, SIGNAL(aboutToQuit()), &app, SLOT(quit()) );

Both forms are valid, and I'd like for both forms to be valid in Perl,
too.

In my Perl bindings, every method call goes through 1 AUTOLOAD sub.
From the information in the AUTOLOAD sub, I have to determine the
correct C++ method to call. The only reliable information is the
$AUTOLOAD variable, which tells me 1) the name of the method being
called and 2) the package that method is in. The other information I
need to know is how many arguments were passed. Unfortunately,
because $_[0] (or, since I'm in XS, ST(0)), may be the object doing
the call, I can't rely on the "items" variable. It might be 1 more
than the number of arguments passed, it might not.



Let's say I have the following C++ methods:
static QObject::doSomethingWith( QObject*, QObject* );
QObject::doSomethingWith( QObject* );

to call those methods in Perl I'd write:
QObject::doSomethingWith( $object1, $object2 );
$object1->doSomethingWith( $object2 );

Then in AUTOLOAD I get the same information for both methods:
$AUTOLOAD = 'QObject::doSomethingWith'
@_ = ( $object1, $object2 )

If I could differentiate between the instance method ("$object1-
>doSomethingWith") and the "static" method

("QObject::doSomethingWith"), then I could determine the correct C++
method to call.

I do have a workaround for this, but it's pretty hack-tastic, and I'm
trying to see if there's a cleaner solution. But it's looking like
Perl doesn't supply me with the information I'm looking for.
 
Reply With Quote
 
sisyphus
Guest
Posts: n/a
 
      11-18-2010
On Nov 18, 1:58*pm, "Uri Guttman" <(E-Mail Removed)> wrote:
> >>>>> "s" == sisyphus *<(E-Mail Removed)> writes:

>
> * s> Not entirely sure that the logic caters for all possibilities, butyou
> * s> should get the idea.
>
> and if you read my reply, you will see that this is a big mistake. one
> sub should not be called with different apis. the whole question is
> wrong.


Yes, I've read your reply.

Cheers,
Rob
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
detecting constructor called before main 440gtx@email.com C++ 2 02-01-2007 07:21 AM
xsub and gcc 4.0.2, static variables thorsten kracht Perl Misc 1 03-06-2006 09:45 AM
threads, XSUB allocated memory, destructors, destruction Andrew Torda Perl Misc 16 10-10-2005 04:36 PM
Detecting when a called function has finsihed Kevin ASP General 1 11-20-2003 09:57 PM
XS/XSUB FAQs? Tutorials? Jeff Perl Misc 2 09-26-2003 11:29 AM



Advertisments