Search code examples
functionmodulerakurakudo

Making exported functions in submodules accessible in global namespace in Raku


I created a minimal working module called new. The folder structure, link here is as follows:

new
│   .gitignore
│   Changes
│   dist.ini
│   LICENSE
│   META6.json
│   README.md
│
├───lib
│   │   new.rakumod
│   │
│   ├───Desc
│   │       Mean.rakumod
│   │
│   └───Deviation
│           DeviationMean.rakumod
│
└───t
        01-basic.rakutest

I have two functions, mean in Desc::Mean.rakumod and deviation_from_mean in Deviation::DeviationMean.rakumod modules in lib. These are simple functions, I don't want to have any namespace defined for them. So when I install this module, and try to use this module with use new, I want to be able to access these two functions without calling their sub-module names.

What I want to do is (which does not work now)

use new;

my @test1 = [6,6,4,6,8,6,8,4,4,6,6,8,8,8,8,8,8,4,4,4,4,8,8,8,8,4,4,4,8,6,8,4];
say mean(@test1);
say deviation_from_mean(@test1);

instead of (which works)

use new;
use Desc::Mean;
use Deviation::DeviationMean;

my @test1 = [6,6,4,6,8,6,8,4,4,6,6,8,8,8,8,8,8,4,4,4,4,8,8,8,8,4,4,4,8,6,8,4];
say mean(@test1);
say deviation_from_mean(@test1);

Is there a way to do this?


Solution

  • # main.raku
    use lib 'lib';
    use new;
    say mean; # 42
    
    # Desc::Mean
    unit module Desc::Mean;
    sub mean is export { 42 }
    
    # new
    sub EXPORT {
      {
        use Desc::Mean;
        return ::.pairs.grep(*.key ne '$_').Map;
      }
    }
    unit module new;
    

    Notes:

    • The sub EXPORT { ... } in the new module must come before the unit module new; statement.

    • use further modules (eg Deviation::DeviationMean) as desired in the EXPORT sub to import those module's symbols into the new compunit; the return ::.pairs.grep(*.key ne '$_').Map; will then re-export all their symbols to whatever uses new.

    For an explanation of the above see: