Importing functions / routines into a subclass

I am using Moops

and I would like something like this to work:

use Moops;

class A {
  fun f {
    print "yay,f!\n";
  }
}

class B extends A {
  fun g {
    f();
  }
}
B->g(); # should print 'yay, f!'

      

Instead, this gives:

Undefined subroutine &B::f called at static-functions-lexical-scope.pl line 11.

      

I can "fix" this by inheriting from Exporter

in A

and use

in B

as follows:

class A extends Exporter {
  our @EXPORT = qw(f);
  fun f {
    print "yay,f!\n";
  }
}

class B extends A {
  use A;
  fun g {
    f();
  }
}

      

This seems a little cumbersome, but gets worse if A

defined in another file. Then I would have to add a second use A

( require

won't do) outside B

like so:

use  A;
class B extends A {
  use A;
  fun g {
    f();
  }
}

      

Is there a way to more elegantly use the lexical include (exported) functions?

+3


source to share


1 answer


First, thanks for using Moops! :-)

Secondly, it's probably a bad idea to name classes "B" in tests and examples. There's a module called B

that comes with Perl, and Moops actually uses it!

Coming to your actual question, generally speaking with classes, you should be thinking method

, not fun

. The method commands respect for inheritance; function calls are not executed.

use Moops;

class AAA {
  method f {
    say "yay,f!";
  }
}

class BBB extends AAA {
  method g {
    $self->f;
  }
}

BBB->g;

      

Outputs:

yay,f!

      

If you want a library of convenience functions to be available both in AAA

and out BBB

, split these convenience functions into a separate package:



use Moops;

namespace MyUtils {
  use Exporter::Shiny qw( f );
  fun f {
    say "yay,f!";
  }
}

class AAA {
  use MyUtils -all;
  method m1 {
    f();
  }
}

class BBB extends AAA {
  use MyUtils -all;
  method m2 {
    f();
  }
}

BBB->m1;
BBB->m2;

      

Outputs:

yay,f!
yay,f!

      

You can even go a little further and expand Moops from the inside out. The following example defines a property :utils

that can be added to classes:

use Moops;

namespace MyUtils {
  use Exporter::Shiny qw( f );
  fun f {
    say "yay,f!";
  }
}

role Moops::TraitFor::Keyword::utils {
   around generate_package_setup {
     return (
       $self->$next(@_),
       'use MyUtils -all;',
     );
   }
}

class AAA :utils {
  method m1 {
    f();
  }
}

class BBB extends AAA :utils {
  method m2 {
    f();
  }
}

BBB->m1;
BBB->m2;

      

The same conclusion as in the previous example.

+5


source







All Articles