Module introspection
You can inspect the namespace of an imported module, for example:
$ perl -MLWP::UserAgent -d -e 1 Loading DB routines from perl5db.pl version 1.32 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): 1 DB<1> x \%{'LWP::UserAgent::'} 0 HASH(0x9dee070) 'BEGIN' => *LWP::UserAgent::BEGIN 'ISA' => *LWP::UserAgent::ISA 'VERSION' => *LWP::UserAgent::VERSION '__ANON__[/usr/share/perl5/LWP/UserAgent.pm:608]' => *LWP::UserAgent::__ANON__[/usr/share/perl5/LWP/UserAgent.pm:608] '__ANON__[/usr/share/perl5/LWP/UserAgent.pm:611]' => *LWP::UserAgent::__ANON__[/usr/share/perl5/LWP/UserAgent.pm:611] '__ANON__[/usr/share/perl5/LWP/UserAgent.pm:632]' => *LWP::UserAgent::__ANON__[/usr/share/perl5/LWP/UserAgent.pm:632] '__ANON__[/usr/share/perl5/LWP/UserAgent.pm:635]' => *LWP::UserAgent::__ANON__[/usr/share/perl5/LWP/UserAgent.pm:635] '__ANON__[/usr/share/perl5/LWP/UserAgent.pm:735]' => *LWP::UserAgent::__ANON__[/usr/share/perl5/LWP/UserAgent.pm:735] '_agent' => *LWP::UserAgent::_agent '_need_proxy' => *LWP::UserAgent::_need_proxy '_new_response' => *LWP::UserAgent::_new_response '_process_colonic_headers' => *LWP::UserAgent::_process_colonic_headers 'add_handler' => *LWP::UserAgent::add_handler 'agent' => *LWP::UserAgent::agent 'clone' => *LWP::UserAgent::clone 'conn_cache' => *LWP::UserAgent::conn_cache 'cookie_jar' => *LWP::UserAgent::cookie_jar 'credentials' => *LWP::UserAgent::credentials 'default_header' => *LWP::UserAgent::default_header 'default_headers' => *LWP::UserAgent::default_headers 'env_proxy' => *LWP::UserAgent::env_proxy 'from' => *LWP::UserAgent::from 'get' => *LWP::UserAgent::get 'get_basic_credentials' => *LWP::UserAgent::get_basic_credentials 'get_my_handler' => *LWP::UserAgent::get_my_handler 'handlers' => *LWP::UserAgent::handlers 'head' => *LWP::UserAgent::head 'import' => *LWP::UserAgent::import 'is_protocol_supported' => *LWP::UserAgent::is_protocol_supported 'local_address' => *LWP::UserAgent::local_address 'max_redirect' => *LWP::UserAgent::max_redirect 'max_size' => *LWP::UserAgent::max_size 'mirror' => *LWP::UserAgent::mirror 'new' => *LWP::UserAgent::new 'no_proxy' => *LWP::UserAgent::no_proxy 'parse_head' => *LWP::UserAgent::parse_head 'post' => *LWP::UserAgent::post 'prepare_request' => *LWP::UserAgent::prepare_request 'progress' => *LWP::UserAgent::progress 'protocols_allowed' => *LWP::UserAgent::protocols_allowed 'protocols_forbidden' => *LWP::UserAgent::protocols_forbidden 'proxy' => *LWP::UserAgent::proxy 'redirect_ok' => *LWP::UserAgent::redirect_ok 'remove_handler' => *LWP::UserAgent::remove_handler 'request' => *LWP::UserAgent::request 'requests_redirectable' => *LWP::UserAgent::requests_redirectable 'run_handlers' => *LWP::UserAgent::run_handlers 'send_request' => *LWP::UserAgent::send_request 'set_my_handler' => *LWP::UserAgent::set_my_handler 'show_progress' => *LWP::UserAgent::show_progress 'simple_request' => *LWP::UserAgent::simple_request 'timeout' => *LWP::UserAgent::timeout 'use_alarm' => *LWP::UserAgent::use_alarm 'use_eval' => *LWP::UserAgent::use_eval DB<2>
Determining specific types of the values in the namespace
Functions:
DB<1> %ns = %{'LWP::UserAgent::'} DB<4> p join ", ", grep { defined &{$ns{$_}} } keys %ns run_handlers, set_my_handler, post, default_headers, prepare_request, credentials, clone, requests_redirectable, timeout, new, parse_head, request, send_request, head, _new_response, conn_cache, protocols_forbidden, show_progress, _need_proxy, no_proxy, protocols_allowed, local_address, use_eval, get_basic_credentials, remove_handler, proxy, max_size, add_handler, mirror, get_my_handler, simple_request, from, get, env_proxy, _agent, max_redirect, redirect_ok, progress, use_alarm, handlers, default_header, _process_colonic_headers, is_protocol_supported, agent, cookie_jar
Scalars:
DB<5> p join ", ", grep { defined ${$ns{$_}} } keys %ns VERSION
Arays:
DB<7> p join ", ", grep { defined @{$ns{$_}} } keys %ns ISA
Another example - not in the debugger
Source:
use strict; use warnings; package wibble; use vars qw($apple @fish %moose); our $cat_undefined; our $cat_defined = "meow"; my $hiddenval = 42; package main; use Data::Dumper; my %b_ns = do { no strict "refs"; %{"wibble::"} }; print Dumper(\%b_ns); print "\n"; print "wibble::apple exists: " . do { exists $b_ns{apple} ? 'yes' : 'no' } . "\n"; print "wibble::hiddenval exists: " . do { exists $b_ns{hiddenval} ? 'yes' : 'no' } . "\n"; print "\n"; print '$wibble::apple defined: ' . do { defined $wibble::apple ? 'yes' : 'no' } . "\n"; print '@wibble::apple defined: ' . do { defined @wibble::apple ? 'yes' : 'no' } . "\n"; print '%wibble::apple defined: ' . do { defined %wibble::apple ? 'yes' : 'no' } . "\n"; print '*wibble::apple defined: ' . do { defined *wibble::apple ? 'yes' : 'no' } . "\n"; print "\n"; print '$wibble::cat_defined defined: ' . do { defined $wibble::cat_defined ? 'yes' : 'no' } . "\n"; print '@wibble::cat_defined defined: ' . do { defined @wibble::cat_defined ? 'yes' : 'no' } . "\n"; print '%wibble::cat_defined defined: ' . do { defined %wibble::cat_defined ? 'yes' : 'no' } . "\n"; print '*wibble::cat_defined defined: ' . do { defined *wibble::cat_defined ? 'yes' : 'no' } . "\n";
Output:
$VAR1 = { 'apple' => *wibble::apple, 'cat_undefined' => *wibble::cat_undefined, 'BEGIN' => *wibble::BEGIN, 'cat_defined' => *wibble::cat_defined, 'moose' => *wibble::moose, 'fish' => *wibble::fish }; wibble::apple exists: yes wibble::hiddenval exists: no $wibble::apple defined: no @wibble::apple defined: no %wibble::apple defined: no *wibble::apple defined: yes $wibble::cat_defined defined: yes @wibble::cat_defined defined: no %wibble::cat_defined defined: no *wibble::cat_defined defined: yes