in reply to Re: List of subs defined by a file?
in thread List of subs defined by a file?

I tried to generalize your script by substituting $file for file.pm, and when I ran it on a regular script it runs the script in require (so that would need to be suppressed somehow) and when I ran it on a perl module like Tie::Scalar (path supplied by perldoc -l) it gave me nothing, since the module doesn't export globals.

My code, for what it's worth:

#!/usr/bin/perl # listsubs - display list of subroutines in a package or script use strict; my $file=shift @ARGV; { package Query; require $file; } for my $sym ( keys %Query:: ) { no strict 'refs'; print "Query::$sym\n" if defined *{'Query::'.$sym}{CODE}; print "$file: subref \$$sym\n" if ref ${*{'Query::'.$sym}{SCALAR}} e +q 'CODE'; }

I think the right answer to this is to simply grep the file for /^sub/, unless you're trying to get a list of dynamically generated coderefs??

SSF

Replies are listed 'Best First'.
Re^3: List of subs defined by a file?
by shmem (Chancellor) on Dec 21, 2008 at 16:57 UTC
    and when I ran it on a perl module like Tie::Scalar (path supplied by perldoc -l) it gave me nothing, since the module doesn't export globals.

    Well, the script I provided is for the case you mentioned - just a file with subs in it, without any package declaration whatsoever (and inspecting the symbol table hasn't anything to do with what is exported - the ad-hoc package Query doen't export anything, either). Now, Tie::Scalar has a package declaration - package Tie::Scalar; - and the script isn't suitable for that case. You would have to inspect %Tie::Scalar. I'd reach for something else for the general case, maybe even PPI.

    I think the right answer to this is to simply grep the file for /^sub/, unless you're trying to get a list of dynamically generated coderefs??

    That heavily depends on what is "right" for you and the task at hand. More general would be grepping for /^\s*sub/. But that won't give you not only dynamically generated subrefs, but also typeglob-bound code generated at module use, such as generated by Class::Accessor:

    package Foo; BEGIN { our ($VERSION, @ISA, @METHODS); @METHODS = qw(foo bar quux); for my $field (@METHODS) { *{__PACKAGE__.'::'.$field} = sub { my $self = shift @_; if (@_) { return $self->set($field, @_); } else { return $self->get($field); } }; } for (qw(set get)) { *{__PACKAGE__.'::'.$_} = sub { my $self = shift @_; if (@_ == 1) { return $$self{$_[0]}; } elsif (@_ > 1) { return $self->{$_[0]} = $_[1]; } else { $self->_croak('Wrong number of arguments received'); } }; } }