in reply to Re: Rename/Relocate A Module
in thread Rename/Relocate A Module

Update: After further testing, I don't think this is a good solution. The symbol tables do not behave as I thought they would.

#!/usr/bin/perl # use Data::Dumper; package Test; $xxx = 10; $yyy = 15; package Test2; $zzz = 20; sub myprint { print "myprint says: $aaa\n"; } package main; $x = 1; print "Before copying symbol table:\n"; print Dumper(\%Test::); print Dumper(\%Test2::); print *{Test2::aaa}{PACKAGE} . ", " . *{Test2:aaa}{NAME} . "\n"; %Test2:: = %Test::; print "After copying symbol table:\n"; print Dumper(\%Test::); print Dumper(\%Test2::); ${Test2::aaa} = 50; print "After assigning to \$Test::aaa:\n"; print Dumper(\%Test::); print Dumper(\%Test2::); print "\$Test2::aaa = $Test2::aaa\n"; print join(' ', keys(%Test2::)) . "\n"; print *{Test2::aaa}{PACKAGE} . ", " . *{Test2:aaa}{NAME} . "\n"; print "\%main:::\n"; print Dumper(\%main::); Test2::myprint();

produces

Before copying symbol table: $VAR1 = { 'xxx' => *Test::xxx, 'yyy' => *Test::yyy }; $VAR1 = { 'myprint' => *Test2::myprint, 'aaa' => *Test2::aaa, 'zzz' => *Test2::zzz }; Test2, Test2:aaa After copying symbol table: $VAR1 = { 'xxx' => *Test::xxx, 'yyy' => *Test::yyy }; $VAR1 = { 'xxx' => *Test::xxx, 'yyy' => *Test::yyy }; After assigning to $Test::aaa: $VAR1 = { 'xxx' => *Test::xxx, 'yyy' => *Test::yyy }; $VAR1 = { 'xxx' => *Test::xxx, 'yyy' => *Test::yyy }; $Test2::aaa = 50 xxx yyy Test2, Test2:aaa %main::: $VAR1 = { '/' => *{'::/'}, 'stderr' => *::stderr, 'SIG' => *::SIG, 'utf8::' => *{'::utf8::'}, '1' => *{'::1'}, '"' => *{'::"'}, 'ARNING_BITS' => *{'::ARNING_BITS'}, 'CORE::' => *{'::CORE::'}, 'DynaLoader::' => *{'::DynaLoader::'}, '_<DynaLoader.c' => *{'::_<DynaLoader.c'}, 'stdout' => *::stdout, 'attributes::' => *{'::attributes::'}, '' => *{'::'}, 'stdin' => *::stdin, '_</usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/Data/Du +mper/Dumper.so' => *{'::_</usr/lib/perl5/5.8.8/i386-linux-thread-mult +i/auto/Data/Dumper/Dumper.so'}, 'ARGV' => *::ARGV, 'INC' => *::INC, 'Scalar::' => *{'::Scalar::'}, 'ENV' => *::ENV, 'Regexp::' => *{'::Regexp::'}, 'Test::' => *{'::Test::'}, 'XSLoader::' => *{'::XSLoader::'}, 'UNIVERSAL::' => *{'::UNIVERSAL::'}, 'overload::' => *{'::overload::'}, '$' => *{'::$'}, '_<perlio.c' => *{'::_<perlio.c'}, 'B::' => *{'::B::'}, 'Test2:aaa' => *{'::Test2:aaa'}, 'x' => *::x, 'main::' => *{'::main::'}, 'Carp::' => *{'::Carp::'}, 'Data::' => *{'::Data::'}, '-' => *{'::-'}, '_<perlmain.c' => *{'::_<perlmain.c'}, 'PerlIO::' => *{'::PerlIO::'}, '_<universal.c' => *{'::_<universal.c'}, '0' => *{'::0'}, 'BEGIN' => *::BEGIN, ' => *{':'}, '@' => *{'::@'}, '_<xsutils.c' => *{'::_<xsutils.c'}, 'Test2::' => *{'::Test2::'}, '!' => *{'::!'}, 'STDOUT' => *::STDOUT, 'IO::' => *{'::IO::'}, '' => *{'::'}, '' => *{'::'}, '_' => *::_, '+' => *{'::+'}, 'Dumper' => *::Dumper, 'Exporter::' => *{'::Exporter::'}, '_<Dumper.c' => *{'::_<Dumper.c'}, 'bytes::' => *{'::bytes::'}, 'STDERR' => *::STDERR, 'Internals::' => *{'::Internals::'}, 'STDIN' => *::STDIN, 'warnings::' => *{'::warnings::'}, 'Config::' => *{'::Config::'}, 'DB::' => *{'::DB::'}, '<none>::' => *{'::<none>::'} }; myprint says: 50

After copying the symbol table all trace of the subroutine myprint and the scalar variable $aaa are gone from %Test2::, yet the subroutine can still be called and the value of $aaa can still be set and used. So where are they? Not in the hash %Test2::, which is where I thought they would be. And what is $Test2::aaa referring to? Obviously not $Test2::{aaa}, which is what I thought it was referring to. I have fallen into a deep pit of mysteries and lost my way...

Or, for more segregation between the old and new modules, you can copy the entire symbol table.

#!/usr/bin/perl use strict; use warnings; BEGIN { package New::MyModule; *Old::MyModule:: = \*New::MyModule::; %My::Other::Name:: = %New::MyModule::; sub foo { print @_ } 1; } New::MyModule::foo("new\n"); Old::MyModule::foo("old\n"); My::Other::Name::foo("other\n"); $New::MyModule::extra1 = 'set as $New::MyModule::extra1'; $Old::MyModule::extra2 = 'set as $Old::MyModule::extra2'; $My::Other::Name::extra3 = 'set as $My::Other::Name::extra3'; # This is to avoid warnings about the above being used only once my @array = ( $New::MyModule::extra1, $Old::MyModule::extra2, $My::Other::Name::extra3, ); print "\nNew::MyModule:\n"; foreach my $key (keys %New::MyModule::) { print "$key: $New::MyModule::{$key}\n"; } print "\nOld::MyModule:\n"; foreach my $key (keys %Old::MyModule::) { print "$key: $Old::MyModule::{$key}\n"; } print "\nMy::Other::Name:\n"; foreach my $key (keys %My::Other::Name::) { print "$key: $My::Other::Name::{$key}\n"; }

Which produces:

new old other New::MyModule: extra2: *New::MyModule::extra2 extra1: *New::MyModule::extra1 foo: *New::MyModule::foo Old::MyModule: extra2: *New::MyModule::extra2 extra1: *New::MyModule::extra1 foo: *New::MyModule::foo My::Other::Name: extra3: *My::Other::Name::extra3 foo: *New::MyModule::foo