R – “Can’t call method “dir_path” on an undefined value” when running Mason component on the command line

apachecommand-linemasonperlunit-testing

Greetings,

I'm trying to develop some tests for Mason components which requires running them on the command line instead of the web server. When I try this, I get an error:

perl -MHTML::Mason::Request -MHTML::Mason::Interp -I./lib \
-e '$int = HTML::Mason::Interp->new( data_dir => "/home/friedo/cache", comp_root => "/home/friedo/comps" ); $m = HTML::Mason::Request->new( comp => "/dummy", interp => $int ); $m->comp("/dummy")'

Results in:

Can't call method "dir_path" on an undefined value at lib/HTML/Mason/Request.pm line 1123.

The error is thrown when the call to ->comp is attempted. I can't figure out what's wrong with the configuration. The component is there and appears to be compiled just fine, and it works via Apache.

This is using HTML::Mason 1.35.

Edit: Let's try a bounty for this one. The alternative is me having to dive deep into Mason's guts! 🙂

Edit again: Thanks very much to David for pointing out the crucial detail that I missed for getting this to work.

This was actually for a test framework that needed to exercise a module that calls some Mason comps — under normal operation the module is provided with a Mason request object to use for that purpose, but I couldn't get that to work offline. The key was using an Interpreter object instead, so I ended up doing the following, which is a little silly but makes the tests work:

sub _mason_out { 
   ...
   my $buf;
   if ( $ENV{MASON_TEST} ) { 
       my $int = HTML::Mason::Interp->new( comp_root  => $self->{env}->comp_dir,
                                           out_method => \$buf );

       $int->exec( $comp, %args );
   } else { 
       my $m = $self->{mason_object};
       $m->comp( { store => \$buf }, $comp, %args );
   }

   return $buf;
}

Best Solution

I think this fails because your Request object hasn't built a component stack at the point that it is called. Use the Interp->exec() method instead as described in Using Mason from a Standalone Script

perl -MHTML::Mason::Interp -I./lib \
-e 'HTML::Mason::Interp->new( data_dir => "/home/friedo/cache", comp_root => "/home/friedo/comps" )->exec("/dummy")'