Let's say we have a Moose class like so:
package My::Test ;
use Moose ;
$\="\n";
sub BUILDARGS {
my ($pkg,%args) = @_ ;
print defined wantarray ? 'BUILDARGS: SCALAR':'BUILDARGS: VOID' ;
return \%args ;
}
sub BUILD {
print defined wantarray ? 'BUILD: SCALAR':'BUILD: VOID' ;
my ( $self, $args ) = @_ ;
print '---' ;
}
1;
Instantiating the class in both SCALAR and VOID context I get always the same output:
#!/usr/bin/perl
use Moose ;
use My::Test ;
# Scalar ctx
my $instance = My::Test->new ;
# Void ctx
My::Test->new ;
Output:
BUILDARGS: SCALAR
BUILD: VOID
---
BUILDARGS: SCALAR
BUILD: VOID
I was able to get the context wrapping the Moose class instance creation in a trivial package and passing the context as constructor attribute as follows:
package My::Wrapper ;
use My::Test ;
sub new {
my ( $class , %args ) = @_ ;
return My::Test->new(%args , ctx => defined wantarray ? 'scalar':'void') ;
}
1 ;
but I would like to know if there is a cleaner way for doing that.
Moose creates the constructor for you (see here). The context isn't propagated to either BUILDARGS or BUILD.
You can wrap new
in the Moose way, though:
around new => sub {
my ($orig, $self) = splice @_, 0, 2;
warn defined wantarray ? 'other' : 'void';
$self->$orig(@_)
};