Danny has asked for the wisdom of the Perl Monks concerning the following question:

I have a package from which the only object is created and this package inherits from a bunch of different packages/files. I want these in different files to keep things organized by purpose/topic. I take it this is frowned upon, but I'm unsure what the better general solutions are. Any advice?

Replies are listed 'Best First'.
Re: multiple inheritance alternative(s)?
by hippo (Archbishop) on Oct 09, 2024 at 22:43 UTC
    I take it this is frowned upon

    I heard some folks argue against it but am not aware of it being universally derided. If you know the arguments against and are happy to ignore or downplay them, then that's fine.

    I want these in different files to keep things organized by purpose/topic

    That sounds more like Roles to me. I don't think anybody argues against applying multiple roles to one class/object. Maybe that's what you're looking for?


    🦛

      Or if not roles perhaps he should have more subsidiary classes and the primary object should have a has-a relation with those instead of it being isa everything. *Cough cough mumble* FacadePattern . . .

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

        To add an example, I have a toy project Filesys::DB, and there are various maintenance operations for the database:

        1. Scan new entries
        2. Scan existing entries for changes
        3. Maintenance of cache tables
        4. ...

        First I also had these within the scripts implementing these operations. Then I moved them into Filesys/DB.pm, and now I have Filesys/DB/Operation.pm, in which these operations live. In the longer run, the operations will likely move into their own sub-files.

        As an example, moving a method from the main class into another module/class can be done like this with Moo:

        # Old version package My::Example; use 5.020; use Moo 2; use experimental 'signatures'; sub do_foo( $self, %options ) { ... }
        # New version version package My::Example; use 5.020; use Moo 2; use experimental 'signatures'; has 'operation_foo' => ( is => 'lazy', default => sub { My::Example::Operation::Foo->new(), }, handles => ['do_foo'], ); package My::Example::Operation::Foo; use 5.020; use Moo 2; use experimental 'signatures'; sub do_foo( $self, %options ) { .... }

        Using objects for holding code mostly makes sense if the operations don't really need information that lives in the "parent" class.

        Update: choroba spotted a misspelled does where it should have been handles.