Perl6: use module inside other module

Viewed 267

I have 4 files.

  • C:\perlCode2\start.pl6
  • C:\perlCode2\file0.pm6
  • C:\perlCode2\folder1\file1.pm6
  • C:\perlCode2\folder2\file2.pm6

start.pl6 is used to run my program. The 3 module files contain or generate data that is eventually used by start.pl6. I use atom.io to run the code.

Here is the code:

start.pl6:

use v6;
use lib ".";
use file0;
use lib "folder1";
use file1;
use lib "folder2";
use file2;

say 'start';
my $file0 = file0.new();
say $file0.mystr;
my $file1 = file1.new();
say $file1.mystr;
my $file2 = file2.new();
say $file2.mystr;
say 'end';

file0.pm6:

class file0 is export {
  has Str $.mystr = "file 0";

  submethod BUILD() {
    say "hello file 0";
  }
}

file1.pm6:

class file1 is export {
  has Str $.mystr = "file 1";
}

file2.pm6:

class file2 is export {
  has Str $.mystr = "file 2";
}

output:

start
hello file 0
file 0
file 1
file 2
end
[Finished in 0.51s]

Rather than making instances of all 3 module files inside start.pl6, I want to create an instance of file2 inside file1, and of file1 inside file0. This way I only have to create an instance of file0 in start.pl6 to see the same output;

Here are the changes I had in mind:

file1.pm6:

use lib "../folder2";
use "file2.pl6"; 

class file1 is export {
  has Str $.mystr = "file 1";

  submethod BUILD() {
    my $file2 = file2.new();
    $!mystr = $!mystr ~ "\n" ~ $file2.mystr; 
        # I want to instantiate file2 inside the constructor, 
        # so I can be sure the line
        # $!mystr = $!mystr ~ "\n" ~ $file2.mystr; 
        # takes effect before i call any of file0's methods;
  }
}

file0.pm6:

use lib "folder1";
use "file1.pl6"; 

class file0 is export {
  has Str $.mystr = "file 0";

  submethod BUILD() {
    say "hello file 0";
    my $file1 = file1.new();
    $!mystr = $!mystr ~ "\n" ~ $file1.mystr; 
  }
}

In file0, the lines use lib "folder1"; use "file1.pl6"; yields this error:

===SORRY!=== Error while compiling C:\perlCode2\file0.pm6 (file0)
'use lib' may not be pre-compiled
at C:\perlCode2\file0.pm6 (file0):2
------> use lib "folder1/file1.pl6"<HERE>;
[Finished in 0.584s]

I file1, the line use lib "../folder2"; use "file2"; doesnt work but also doesnt give an error. I just get the output: [Finished in 0.31s]

In the end, the file start.pl6 should look like this to produce the output:

start.pl6:

use v6;
use lib ".";
use file0;

say 'start';
my $file0 = file0.new();
say $file0.mystr;
say 'end';

output:

start
hello file 0
file 0
file 1
file 2
end
2 Answers

What you are trying to do makes no sense to me. It seems you are putting those modules in folders arbitrarily.


If the names of those modules does make sense here is how I might structure it.

C:\perlCode2\start.pl6
C:\perlCode2\lib\file0.pm6
C:\perlCode2\lib\folder1\file1.pm6
C:\perlCode2\lib\folder2\file2.pm6

start.pl6:

use v6;

END say "[Finished in {(now - $*INIT-INSTANT).fmt("%0.2fs")}";

use lib 'lib';
use file0;

say 'start';
my $file0 = file0.new;
say $file0.mystr;
say 'end';

lib\file0.pm6:

use folder1::file1;

class file0 is export {
  has Str $.mystr = "file 0";

  submethod TWEAK() {
    say "hello file 0";
    $!mystr ~= "\n" ~ folder1::file1.new.mystr; 
  }
}

lib\folder1\file1.pm6:

use folder2::file2;

class folder1::file1 is export {
  has Str $.mystr = "file 1";

  submethod TWEAK() {
    $!mystr ~= "\n" ~ folder2::file2.new.mystr;
  }
}

lib\folder2\file2.pm6

class folder2::file2 is export {
  has Str $.mystr = "file 2";
}

use lib "folder2/file2.pl6";

This does not do what you think it does. use lib expects a directory where Perl should be looking for modules, not the path to some script.

If your My.pm6 is in ./lib (in respect to the current working directory) then

use lib "lib";
use My;

does the trick. You can also use absolute paths

use lib "~/projects/perl6/MyProject/lib";
use My;

See lib.

Related