Package alias for enabling dual-use namespaces

I have an interesting situation. Some (large) legacy code has a namespace that should look like require A::B, but instead a path to A was added, so you can just say require B. However, I would like to be able to use both calls. Is this possible without creating a redirect package? For example, is there a way to double-declare a package?

Thank!

+3
source share
3 answers

First download the package:

require A::B;

Then add an alias Bto A::B:

*B:: = *A::B::;

Then say requirethat it has already downloadedB

$INC{'B.pm'}++;

, , BEGIN:

BEGIN {
    require A::B;
    *B:: = *A::B::;
    $INC{'B.pm'}++;
}

require A::B; require B; . . \&A::B::foo == \&B::foo

, :

  • A/B.pm

    *B:: = *A::B::;
    $INC{'B.pm'}++;
    
  • B.pm

    *A::B:: = *B::;
    $INC{'A/B.pm'}++;
    

, require A::B;, A::B::foo B::foo, require B; no-op.

require B;, A::B::foo B::foo, require A::B; no-op.

( ) , . , A/B.pm :

  • A/B.pm

    *B:: = *A::B::;  # this gets added to the existing file
    $INC{'B.pm'}++;
    
  • B.pm

    require A::B;  # this is the entire file
    
+16

require Something @INC Something.pm. some-path/A/B.pm require B require A::B, some-path, some-path/A @INC.

, @INC.

+2

, , , , . , , Package:: Stash, , ? , . , ?

require B; A:: B - lib/, A/B.pm:

cd lib
ln -sf -T A/B.pm B.pm

Please note that this will create two packages with the same code, so the variables in one will not have the same value as the other: they $A::B::foowill be completely separate from $B::foo, although their declaration comes from the same file.

+1
source

Source: https://habr.com/ru/post/1790563/


All Articles