Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.7 KiB

  1. package Symbol;
  2. =head1 NAME
  3. Symbol - manipulate Perl symbols and their names
  4. =head1 SYNOPSIS
  5. use Symbol;
  6. $sym = gensym;
  7. open($sym, "filename");
  8. $_ = <$sym>;
  9. # etc.
  10. ungensym $sym; # no effect
  11. print qualify("x"), "\n"; # "Test::x"
  12. print qualify("x", "FOO"), "\n" # "FOO::x"
  13. print qualify("BAR::x"), "\n"; # "BAR::x"
  14. print qualify("BAR::x", "FOO"), "\n"; # "BAR::x"
  15. print qualify("STDOUT", "FOO"), "\n"; # "main::STDOUT" (global)
  16. print qualify(\*x), "\n"; # returns \*x
  17. print qualify(\*x, "FOO"), "\n"; # returns \*x
  18. use strict refs;
  19. print { qualify_to_ref $fh } "foo!\n";
  20. $ref = qualify_to_ref $name, $pkg;
  21. use Symbol qw(delete_package);
  22. delete_package('Foo::Bar');
  23. print "deleted\n" unless exists $Foo::{'Bar::'};
  24. =head1 DESCRIPTION
  25. C<Symbol::gensym> creates an anonymous glob and returns a reference
  26. to it. Such a glob reference can be used as a file or directory
  27. handle.
  28. For backward compatibility with older implementations that didn't
  29. support anonymous globs, C<Symbol::ungensym> is also provided.
  30. But it doesn't do anything.
  31. C<Symbol::qualify> turns unqualified symbol names into qualified
  32. variable names (e.g. "myvar" -E<gt> "MyPackage::myvar"). If it is given a
  33. second parameter, C<qualify> uses it as the default package;
  34. otherwise, it uses the package of its caller. Regardless, global
  35. variable names (e.g. "STDOUT", "ENV", "SIG") are always qualified with
  36. "main::".
  37. Qualification applies only to symbol names (strings). References are
  38. left unchanged under the assumption that they are glob references,
  39. which are qualified by their nature.
  40. C<Symbol::qualify_to_ref> is just like C<Symbol::qualify> except that it
  41. returns a glob ref rather than a symbol name, so you can use the result
  42. even if C<use strict 'refs'> is in effect.
  43. C<Symbol::delete_package> wipes out a whole package namespace. Note
  44. this routine is not exported by default--you may want to import it
  45. explicitly.
  46. =cut
  47. BEGIN { require 5.002; }
  48. require Exporter;
  49. @ISA = qw(Exporter);
  50. @EXPORT = qw(gensym ungensym qualify qualify_to_ref);
  51. @EXPORT_OK = qw(delete_package);
  52. $VERSION = 1.02;
  53. my $genpkg = "Symbol::";
  54. my $genseq = 0;
  55. my %global = map {$_ => 1} qw(ARGV ARGVOUT ENV INC SIG STDERR STDIN STDOUT);
  56. #
  57. # Note that we never _copy_ the glob; we just make a ref to it.
  58. # If we did copy it, then SVf_FAKE would be set on the copy, and
  59. # glob-specific behaviors (e.g. C<*$ref = \&func>) wouldn't work.
  60. #
  61. sub gensym () {
  62. my $name = "GEN" . $genseq++;
  63. my $ref = \*{$genpkg . $name};
  64. delete $$genpkg{$name};
  65. $ref;
  66. }
  67. sub ungensym ($) {}
  68. sub qualify ($;$) {
  69. my ($name) = @_;
  70. if (!ref($name) && index($name, '::') == -1 && index($name, "'") == -1) {
  71. my $pkg;
  72. # Global names: special character, "^x", or other.
  73. if ($name =~ /^([^a-z])|(\^[a-z])$/i || $global{$name}) {
  74. $pkg = "main";
  75. }
  76. else {
  77. $pkg = (@_ > 1) ? $_[1] : caller;
  78. }
  79. $name = $pkg . "::" . $name;
  80. }
  81. $name;
  82. }
  83. sub qualify_to_ref ($;$) {
  84. return \*{ qualify $_[0], @_ > 1 ? $_[1] : caller };
  85. }
  86. #
  87. # of Safe.pm lineage
  88. #
  89. sub delete_package ($) {
  90. my $pkg = shift;
  91. # expand to full symbol table name if needed
  92. unless ($pkg =~ /^main::.*::$/) {
  93. $pkg = "main$pkg" if $pkg =~ /^::/;
  94. $pkg = "main::$pkg" unless $pkg =~ /^main::/;
  95. $pkg .= '::' unless $pkg =~ /::$/;
  96. }
  97. my($stem, $leaf) = $pkg =~ m/(.*::)(\w+::)$/;
  98. my $stem_symtab = *{$stem}{HASH};
  99. return unless defined $stem_symtab and exists $stem_symtab->{$leaf};
  100. my $leaf_glob = $stem_symtab->{$leaf};
  101. my $leaf_symtab = *{$leaf_glob}{HASH};
  102. %$leaf_symtab = ();
  103. delete $stem_symtab->{$leaf};
  104. }
  105. 1;