Catalyst-View-ByCode

 view release on metacpan or  search on metacpan

lib/Catalyst/View/ByCode.pm  view on Meta::CPAN

        : 0;
    use strict 'refs';
    
    if (!$full_path || !$file_mtime) {
        # we don't know the template or it has vanished somehow
        my $full_path = $c->path_to($self->root_dir, $template_path);
        if (-f $full_path) {
            # found!
            $self->__compile($c, "$full_path" => $package);
        }
    } elsif ($file_mtime != $package_mtime) {
        # we need a recompile
        $self->__compile($c, $full_path => $package);
    }
    
    # important: must stringify method to avoid Log::Log4perl::Catalyst
    #            to call it.
    my $method = $package->can($sub_name);
    $c->log->debug("can run: $method") if $c->debug;
    
    return $method;
}

# low level compile
sub __compile {
    my $self = shift;
    my $c = shift;
    my $path = shift;
    my $package = shift;
    
    # allow meaningful warnings during compile
    local $compiling_package = $package;
    
    $c->log->debug("compile template :: $path --> $package") if $c->debug;
    
    #
    # clear target package's namespace before we start
    #
    no strict 'refs';
    %{*{"$package\::"}} = ();
    use strict 'refs';

    #
    # slurp in the file
    #
    my $file_contents;
    if (open(my $file, '<', $path)) {
        local $/ = undef;
        $file_contents = <$file>;
        close($file);
    } else {
        $c->log->error('Error opening template file $file');
        return; ### FIXME: throw exception is better
    }

    #
    # build some magic code around the template's code
    #
    ### my $include = join("\n", map {"use $_;"} @{$self->include});
    my $now = localtime(time);
    my $mtime = (stat($path))[9];
    my $code = <<PERL;
# auto-generated code - do not modify
# generated by Catalyst::View::ByCode at $now
# original filename: $path

package $package;
use strict;
use warnings;
use utf8;

# use Devel::Declare(); ### do we need D::D ?
${ \join("\n", map { "use $_;" } @{$self->include}) }
use Catalyst::View::ByCode::Renderer qw(:default);

# subs that are overloaded here would warn otherwise
no warnings 'redefine';
PERL

    # count lines created so far (@lines added to avoid warnings)
    my $header_lines = scalar(my @lines = split(/\n/, $code));

    $code .= "\n$file_contents;\n\n1;\n";
    
    #
    # Devel::Declare does not work well with eval()'ed code...
    #                thus, we need to save into a TEMP-file
    #
    my $tempfile = Path::Class::File->new(File::Spec->tmpdir,
                                          UUID::Random::generate . '.pl');
    $c->log->debug("tempfile = $tempfile") if $c->debug;
    open(my $tmp, '>', $tempfile);
    print $tmp $code;
    close($tmp);
    
    #
    # create some magic _variables
    #
    no strict 'refs';
    ${"$package\::_filename"} = $path;
    ${"$package\::_offset"}   = $header_lines + 1;
    ${"$package\::_mtime"}    = $mtime;
    ${"$package\::_tempfile"} = "$tempfile";
    use strict 'refs';

    #
    # compile that
    #
    my $compile_result = do $tempfile;
    unlink $tempfile;
    if ($@) {
        #
        # error during compile
        #
        $c->error('compile error: ' . _correct_message($package, $@));
        #die "compile error ($package)";
    } elsif (!$compile_result) {
        #
        # compiled template did not return a true value
        #
        $c->error("Template $package did not return a true value");



( run in 1.326 second using v1.01-cache-2.11-cpan-39bf76dae61 )