Search code examples
perlconstructormoose

How can I require a Moose constructor arg that is not a attribute?


I have a Moose object module that should accept a relatively large data structure (ds) as one of its constructor arguments. It is used to calculate some of the object's attributes. However, I do not wish to store ds itself as an attributes -- it is only needed during the construction of the object.

I thought of using BUILDARGS but then I'm not sure how to define that ds is a required argument.

How can I work around this?


Solution

  • I'd be inclined to have a constructor that takes only the calculated values derived from your data structure. Then use a different method to take limited params plus the data structure as args.

    sub generate_foo_from_ds {
        my $class = shift; 
        my %arg = @_;
    
        my $ds = $arg{foo_data};
    
        # Get attributes from args
        my %attrib;
        for (qw(foo bar baz ) {
            croak "Attrib '$_' is required" unless exists $arg{$_};
            $attrib{$_} = $arg{$_};
        }
    
        # calculate some more attributes here.
        $attrib{griz} = $ds->{whee} * $ds->{whoosh} / $ds->{whiz}[12];
    
        my $foo = $class->new( %attrib );
    
        return $foo;
    }
    

    Then make your objects like so:

    my $foo = Foo->generate_foo_from_ds( foo_data => $bar, foo => 1, bar => 2, baz => 2 );
    

    Now you don't have to worry about weird serialization issues or BUILDARGS or even BUILD. You have a simple method and that is all.