willyjoker
willyjoker

Reputation: 877

Can I know which child class am I from parent's code in Moose?

I am creating a set of small Perl programs which will be run like a CLI. I want all of them to share some features, eg. same input/output format (probably JSON). I also want each component to be black-box testable with mock arguments. This is what I have so far:

What I want to achieve with this is that, when I run perl actionX.pm arguments from command line, some code in abstractAction.pm will:

  1. Read JSON/whatever from @ARGV and convert it to Perl data structures.

  2. This part is not clear: know that it was called from/as actionX, so it knows that if actionX consumes role needDB, it will need to get a database handler to pass it to run, etc.

  3. Call actionX->run() passing the data object and any handler obtained at step 2.


I tried using both run() and __PACKAGE__->run() in abstractAction.pm, but it calls the superclass method, not the child's. Is there any way I can know the child's package name from the parent? That doesn't even sound good. Is there a better way to do what I am trying to achieve?

I know I could simply do perl abstractAction.pm actionX arguments instead of perl actionX.pm arguments and call it a day, but I'd rather not.

Upvotes: 0

Views: 112

Answers (1)

ikegami
ikegami

Reputation: 385897

Fundamentally, you'll need to call run as a method, using the name of the child class (if it's a class method) or an object of the child class (if it's an instance method) as the invocant.

Calling run as a class method:

ActionX->run(...)

Calling run as an instance method:

ActionX->new(...)->run(...)

The other issue is that you're executing a .pm file, which leads to problems. Load modules, don't execute them. For example,

#!/usr/bin/perl
use strict;
use warnings;

my $action = shift(@ARGV)
   or die("usage\n");

$action =~ /^\w+\z/
   or die("Bad action\n");

my $pkg = $action;   # Or: my $pkg = "...::" . $action;

my $module =~ s{::}{/}g . '.pm';
require $module;

$pkg->new(@ARGV)->run();

If the script is named action, then you can do

action ActionX parameters

Upvotes: 1

Related Questions