For object oriented modules, your approach is fragile and non standard.

Usually, when you need to instantiate objects, but the objects could be of several different classes based on what the user needs, you can use the Builder pattern. When building the builder object, you pass it all the arguments common to all the constructors of the different classes it can instantiate, it can then have several builder methods, one for each class, which take the arguments specific for the class's constructor.

If some of the methods have the same implementation in multiple classes, create an abstract parent class from which all the classes inherit (Foo::Common below), or use roles to implement the methods (not shown in the example below).

OO classes don't usually export anything. To import constants, use a dedicated class.

For a small project, this might seem like a Java-level verbosity. For larger projects, one would get mad at handling the different flags and ternaries in method implementations; with the Builder pattern you always know where to look when you need to see the implementation of a particular behaviour - and if it's not in the file, it tells you where to look further (parent or role).

I've used this at a $job - 2 with tens of constructor parameters, built on Moose. It worked great.

# ./lib/Foo/Classic.pm # -------------------- package Foo::Classic; use warnings; use strict; use feature qw{ say }; use experimental qw( signatures ); use parent 'Foo::Common'; sub style($self) { 'classic' } sub m2($self) { say 'classic 2' } __PACKAGE__ # ./lib/Foo/Constants.pm # ---------------------- package Foo::Constants; use warnings; use strict; use Exporter qw{ import }; my %const; BEGIN { %const = ( ABC => 'abc', XYZ => 'xyz', ); } use constant \%const; our @EXPORT_OK = keys %const; __PACKAGE__ # ./lib/Foo/Modern.pm # ------------------- package Foo::Modern; use warnings; use strict; use feature qw{ say }; use experimental qw( signatures ); use parent 'Foo::Common'; sub style($self) { 'modern' } sub m2($self) { say 'modern 2' } __PACKAGE__ # ./lib/Foo/Builder.pm # -------------------- package Foo::Builder; use warnings; use strict; use experimental qw( signatures ); use Foo::Classic; use Foo::Modern; my %CLASS = (classic => 'Foo::Classic', modern => 'Foo::Modern'); sub new($class) { return bless {}, $class } sub build($self, $style, @args) { my $class = $CLASS{$style}; die "Unknown style $style" unless $class; return $class->new(@args) } __PACKAGE__ # ./lib/Foo/Common.pm # ------------------- package Foo::Common; use warnings; use strict; use feature qw{ say }; use experimental qw( signatures ); sub new($class) { bless {}, $class } sub m1($self) { say $self->style, ' 1' } sub style($self) { die 'Not implemented' } __PACKAGE__ # ./script.pl # ----------- #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use lib 'lib'; use Foo::Builder; use Foo::Constants qw( ABC XYZ ); my $builder = 'Foo::Builder'->new; my $m = $builder->build('modern'); $m->m1; $m->m2; my $c = $builder->build('classic'); $c->m1; $c->m2; say ABC;
Also note that this approach addresses my other comment: you can easily instantiate both the classic and modern objects in the same program.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

In reply to Re: Conditional and opt-in breaking change: is this design viable and my use of 'import' OK? by choroba
in thread Conditional and opt-in breaking change: is this design viable and my use of 'import' OK? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.