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



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")'