Reflection or discovery of object methods in perl?

G

Guest

hello!

again i am trying to get some stuff working (this time CORBA...), and again
i would need an inspection tool telling me what class an object is
and what methods its possesses...

i know UNIVERSAL::can but that one expects a method name, it doesn't spit
out the whole list when not provided with a method name...

so is there that type of mechanism in perl?

thanks
 
A

Anno Siegel

hello!

again i am trying to get some stuff working (this time CORBA...), and again
i would need an inspection tool telling me what class an object is
and what methods its possesses...

The class is easy: perldoc -f ref. Finding all methods can't be done.

One could (conceivably) walk the symbol table of the class and extract
all coderefs (plus, recursively, the classes on @ISA). But there is
no way of telling if a sub is a public method (or a method at all),
so you'd get a lot of garbage besides the actual methods, and no
way to tell one from the other.

Anno
 
G

Guest

The class is easy: perldoc -f ref. Finding all methods can't be done.
hmmm pity....
One could (conceivably) walk the symbol table of the class and extract
all coderefs (plus, recursively, the classes on @ISA). But there is
no way of telling if a sub is a public method (or a method at all),
so you'd get a lot of garbage besides the actual methods, and no
way to tell one from the other.
ok! where do i find those symbol tables?
 
A

Anno Siegel

hmmm pity....

ok! where do i find those symbol tables?

In perldata, perlmod and perlsub, mainly.

Here is an example that lists all subs in main (scratch the "grep"
to see all symbols):

sub foo {} # define a sub, or you won't see much
print "$_\n" for grep defined( &{ $main::{ $_}}), keys %main::

You'll have to use some nasty symrefs to make it use an arbitrary
string instead of "main". That is one of the cases where symrefs
are officially tolerated.

Anno
 
G

Guest

Here is an example that lists all subs in main (scratch the "grep"
to see all symbols):

sub foo {} # define a sub, or you won't see much
print "$_\n" for grep defined( &{ $main::{ $_}}), keys %main::
interesting :D i was planning to use the 'can' method to achieve the same :D
anyway thanks a lot!

making myself an inspection class

ciao
Bruno
 
U

Uri Guttman

AS> Here is an example that lists all subs in main (scratch the "grep"
AS> to see all symbols):

AS> sub foo {} # define a sub, or you won't see much
AS> print "$_\n" for grep defined( &{ $main::{ $_}}), keys %main::

AS> You'll have to use some nasty symrefs to make it use an arbitrary
AS> string instead of "main". That is one of the cases where symrefs
AS> are officially tolerated.

as my rule states, use symrefs only when you are munging (which covers
searching :) the symbol table. :)

uri
 
U

Uri Guttman

B> interesting :D i was planning to use the 'can' method to achieve
B> the same :D anyway thanks a lot!

how would you use can() for introspection? you would have to search all
possible strings and run can() on them.

also with AUTOLOAD you can't fully tell what methods are there. autoload
can handle any method, or decide what is available at run time or
whatever. i find the concept of introspection to be weak and not needed
much. but others seems to live on it. either you know the classes you
want or you don't.

uri
 
G

Guest

how would you use can() for introspection? you would have to search all
possible strings and run can() on them.
yep that's what i do, spares one eval statement...
that way i can separate also what are variables...

BTW a chance to easily try to extrapolate what return type the subs
might have (means without actually executing them...)?
also with AUTOLOAD you can't fully tell what methods are there. autoload
can handle any method, or decide what is available at run time or
sure...
but not in my code :D
whatever. i find the concept of introspection to be weak and not needed
much. but others seems to live on it. either you know the classes you
want or you don't.
well in most cases yes, when you are debugging a non working CORBA
framework (at least non working for me...) with perl objects that have no
(or nearly no) documentation, it can come in quite handy...

ciao
Bruno

Bruno.Boettcher at visualsphere dot com
==============================================================
Unsolicited commercial email is NOT welcome at this email address
 
P

Peter Scott

G

Guest

Hi!

another problem rose now....

uhm might seem stupid, but the ISA array is available only inside the
objects themselves, seems i can't acces them from the outside...

any way to get a hold of the super classes of an object?
 
A

Anno Siegel

BTW a chance to easily try to extrapolate what return type the subs
might have (means without actually executing them...)?

No.

That doesn't even make sense in a Perl context. For one, Perl doesn't have
the concept of data type in the sense C has it. The scalar/array/hash/...
distinction comes closest, in particular in combination with references.
But a function can return any of these at run time, there's no way of
telling unless you analyze the code.

Anno
 
A

Anno Siegel

Hi!

another problem rose now....

uhm might seem stupid, but the ISA array is available only inside the
objects themselves, seems i can't acces them from the outside...

Huh? Can you explain that in code, please? What does it mean to be
"inside" or "outside" an object? @ISA is a package variable and behaves
like one in every aspect.
any way to get a hold of the super classes of an object?

Actually, objects don't have super classes, classes do.

Get the object's class (we've been there already), which is also a package.
Then use (another) symref to access @ISA in that package.

Anno
 
M

Michele Dondi

sub foo {} # define a sub, or you won't see much
print "$_\n" for grep defined( &{ $main::{ $_}}), keys %main::

Dear Anno, please forgive me if I'm dumb: of course I have much less
experience than you have, in these matters, but wouldn't it be better
to grep on

*{$_}{CODE}

instead, especially in a more general setting, since we cannot rely on
return values of subs (and we may risk side effects running them)?

Also, were I doing this for a generic package, say $pkg, rather than
main, should I use something like

*{"${pkg}::$_"}{CODE}

instead? Or are there better ways?

*{ ${"${pkg}::"}{$_} }{CODE}

seems to work, even though I had naively and erroneously assumed that
the outer *{ ... } wouldn't have been necessary, but is even more
verbose and clumsy...


Michele
 
A

Anno Siegel

Michele Dondi said:
Dear Anno, please forgive me if I'm dumb: of course I have much less
experience than you have, in these matters, but wouldn't it be better
to grep on

*{$_}{CODE}

instead, especially in a more general setting, since we cannot rely on
return values of subs (and we may risk side effects running them)?

Uh, no. I'm not running them, that would be suicidal... Also,
as you note, there's no telling what they return.

"defined &foo" is special, it tests if a sub is defined (has code
associated with it). It's the standard way of testing if a sub
exists, I just adapted it to the situation, making use of the fact
that a glob can be de-referenced like a ref. The glob_as_a_hash
syntax you're using just didn't come to mind as readily, so I
used the first thing that worked. How's that for the praxis of
experience? :)
Also, were I doing this for a generic package, say $pkg, rather than
main, should I use something like

*{"${pkg}::$_"}{CODE}

Well... it works.
instead? Or are there better ways?

*{ ${"${pkg}::"}{$_} }{CODE}

seems to work, even though I had naively and erroneously assumed that
the outer *{ ... } wouldn't have been necessary, but is even more
verbose and clumsy...

That looks like an attempt to restrict the symref what's absolutely
necessary. "$_", which went into the symref above, is now a respectable
piece of data (a hash key). But you can't avoid a symref altogether
(I don't think so), so why bother.

Then again, it gains a little when the '::' is made part of $pkg (or
never stripped off in the first place):

*{ ${ $pkg}{ $_}}{ CODE}

doesn't look half bad.

Anno
 
J

Joe Smith

BTW a chance to easily try to extrapolate what return type the subs
might have (means without actually executing them...)?

You are aware, I hope, that subs using wantarray() can return more
than one type, depending on context (list, scalar, void).
-Joe
 
M

Michele Dondi

"defined &foo" is special, it tests if a sub is defined (has code
associated with it). It's the standard way of testing if a sub

My fault, I plainly didn't know! Yet another bit of magic, I see...
incidentally this may be yet another good reason not to use the &-form
of sub call. E.g.:

my $def;
defined &{$_} and $def++ for \&sub1, \&sub2, \&sub3;

will always give me $def==3, IIUC.
Well... it works.
[snip rest]

TY for your helpful cmts.


Michele
 
E

Eric J. Roode

(e-mail address removed)-strasbg.fr () wrote in
hello!

again i am trying to get some stuff working (this time CORBA...), and
again i would need an inspection tool telling me what class an object
is and what methods its possesses...

i know UNIVERSAL::can but that one expects a method name, it doesn't
spit out the whole list when not provided with a method name...

so is there that type of mechanism in perl?

thanks

The 'ref' operator will tell you what class an object is a member of.
(Usually).

There is no real way to list all the methods for a Perl class, because
classes in Perl are allowed to (and sometimes do!) create methods on the
fly, via the AUTOLOAD subroutine. A class can potentially have an
unlimited number of methods, none of which are defined at compile time.

--
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top