4.53. perl

Executes the perl code contained by the tag. The code will run under the restrictions of Perl's Safe module by default. The tag expands to the value returned by the enclosed code (i.e., printing to STDOUT or STDERR is useless).

See also Interchange Programming.

4.53.1. Summary

    [perl tables] Code here [/perl]
    [perl tables="db1 db2 ..." other_named_attributes] Code here [/perl]
Parameters Description Default
tables Database tables to be made available to ASP Perl code none
table Alias for tables none
Attributes Default
failure none
no_return No
subs No
arg="subs" Same as subs
global No
file none
number_errors none
eval_label none
short_errors none
trim_errors none
interpolate No
reparse Yes
Other_Characteristics  
Invalidates cache Yes
Has Subtags No
Container tag Yes

Tag expansion example:

    [perl tables="products" failure="Perl code error <BR>"]
     my $result = "Looked up SKU $Values->{code}. It is a ";
     $result .= $Tag->data('products', 'description', $Values->{code} );
     return ("$result <br>\n");
    [/perl]
---
    Looked up SKU os28044. It is a Framing Hammer <br>

ASP-like Perl call: (e.g., to use it like a runtime eval() within your code)

    $Tag->perl(  { tables  => "products", },
                 $code  );

or similarly with positional parameters,

    $Tag->perl( $tables, $attribute_hash_reference );

4.53.1.1. See Also

See also Interchange Programming, [calc], and [mvasp].

4.53.2. Description

This tag allows you to embed perl code within an Interchange page. The code will run under the restrictions of Perl's Safe module by default. Perl's 'warnings' and 'strict' pragmas are both turned off, and Safe will block you from turning them on, since it blocks Perl's 'use' command. (This is not usually a problem, since you should probably use an alternative such as a usertag if your code is complex enough to need strict.)

The tag expands to the value returned by the enclosed code (i.e., printing to STDOUT or STDERR is useless).

    [perl]
        $name    = $Values->{name};
        $browser = $Session->{browser};
        return "Hi, $name! How do you like your $browser?
    [/perl]

Object references are available for most Interchange tags and functions, as well as direct references to Interchange session and configuration values.

Object Description
$CGI->{key} Hash reference to raw submitted values
$CGI_array->{key} Arrays of submitted values
$Carts->{cartname} Direct reference to shopping carts
$Config->{key} Direct reference to $Vend::Cfg
$DbSearch->array(@args) Do a DB search and get results
$Document->header() Writes header lines
$Document->send() Writes to output
$Document->write() Writes to page
$Scratch->{key} Direct reference to scratch area
$Session->{key} Direct reference to session area
$Tag->tagname(@args) Call a tag as a routine (UserTag too!)
$TextSearch->array(@args) Do a text search and get results
$Values->{key} Direct reference to user form values
$Variable->{key} Config variables (same as $Config->{Variable});
&HTML($html) Same as $Document->write($html);
&Log($msg) Log to the error log

For full descriptions of these objects, see Interchange Perl Objects.

4.53.2.1. tables

This should be a whitespace-separated list of database tables you want to make available within the Perl code.

If you wish to use database values in your Perl code, the tag must pre-open the table(s) you will be using. Here is an example using the products table:

    [perl tables=products]
        my $cost = $Tag->data('products', 'our_cost', $Values->{code});
        $min_price = $cost * ( 1 + $min_margin );
        return ($min_price > $sale_price) ? $min_price : $sale_price;
    [/perl]

If you do not do this, your code will fail with a runtime Safe error when it tries to look up 'our_cost' in the products database with the data tag.

Even if you properly specify the tables to pre-open, some database operations will still be restricted because Safe mode prohibits creation of new objects. For SQL, most operations can be performed if the Safe::Hole module is installed. Otherwise, you may have to set the global=1 attribute to use data from SQL tables.

Interchange databases can always be accessed as long as they are pre-opened by using an item first.

Technical note:

Safe objects (including database handles) may persist within a page, and the perl tag does not necessarily destroy objects created earlier in the page. As a result, your code may work even though you did not set 'tables' properly, only to break later when you change something elsewhere on the page.

For example, this will work because the first call to [accessories ...] opens the (default) products table:

    [accessories code=os28044 attribute=size]

    [perl]
        return $Tag->accessories( { attribute => 'size',
                                    code      => 'os28085' } );
    [/perl]

If you remove the first [accessories ...] tag, then the $Tag->accessories call will fail with a Safe error unless you also set 'tables=products' in the perl tag.

The moral of this story is to ensure that you pass all necessary tables in the perl tag.

4.53.2.2. failure

If your code contains a compile or runtime error and fails to evaluate (i.e., eval($code) would set $@), the tag will return the value set for the failure attribute. The error will be logged as usual.

For example,

    [perl failure="It Broke"]
        my $cost = $Tag->data('products', 'our_cost', $Values->{code});
        $min_price = $cost * ( 1 + $min_margin );
        return ($min_price > $sale_price) ? $min_price : $sale_price;
    [/perl]

will return 'It Broke' because the $Tag->Data(...) call will fail under the Safe module (see tables above).

4.53.2.3. no_return

If no_return=1, this attribute suppresses the return value of the perl code.

You can retrieve the return value from the session hash via [data session mv_perl_result] until it gets overwritten by another perl tag.

If no_return is set, the perl tag will return any output explicitly written with the &HTML or $Document->write() functions.


Note:

If no_return is not set, then the $Document->write() buffer is not returned (unless you use $Document->hot(1) or $Document->send(), in which case the contents of the write buffer will probably appear before anything else on the page). See Interchange Perl Objects for more detail.


Here is an example:

    [perl tables=products no_return=1]
        my $cost = $Tag->data('products', 'our_cost', $Values->{code});
        $min_price = $cost * ( 1 + $min_margin );
        &HTML( ($min_price > $sale_price) ? $min_price : $sale_price );
        return ($min_price > $sale_price) ? 'too low' : 'ok';
    [/perl]

This will put the same price on the page as our earlier example, but

$Session->{mv_perl_result} will be either 'too low' or 'ok'.

The [mvasp] tag is very similar to [perl no_return=1].

4.53.2.4. subs

If you have set the AllowGlobal catalog directive, setting subs=1 will enable you to call GlobalSub routines within the enclosed perl code. Note that this can compromise security.

4.53.2.5. global

If you have set the AllowGlobal catalog directive, setting global=1 will turn off Safe protection within the tag.

The code within the tag will then be able to do anything the user ID running Interchange can. This seriously compromises security, and you should know what you are doing before using it in a public site. It is especially dangerous if a single Interchange server is shared by multiple companies or user IDs.

Also, full 'use strict' checking is turned on by default when in global mode. You can turn it off by using 'no strict;' within your code. Note that any strict errors will go to the Interchange error logs, and the tag itself will fail silently within the page.

4.53.2.6. file

This prepends the contents of the specified file or FileDatabase entry to the enclosed perl code (if any), then executes as usual.

For example,

    [perl file="my_script.pl"][/perl]

would execute myscript.pl and expand to its return value.

Absolute filenames (or filenames containing '../') are prohibited by the NoAbsolute catalog directive.

If the filename is not absolute, Interchange first looks for a file in the current directory, then in the list set with the TemplateDir catalog directive. If it fails to find a file by that name, it then looks for an entry by that name in the database specified with the FileDatabase catalog directive.

4.53.2.7. file

Add line numbers to the source code displayed in the error.log, amazingly useful if some of the perl is being generated elsewhere and interpolated.

4.53.2.8. eval_label

Set to a string, will replace the (eval ###) in the error message with this label, handy to quickly track down bugs when you have more than one perl block in the page, especially if you are using short_errors.

4.53.2.9. short_errors

If set to a true value, syntax errors and the like in perl tags will log just the error, not the whole source code of the block in question, handy when you have the code open in an editor anyway and don't want the error itself to get scrolled away when running 'tail -f error.log'.

4.53.2.10. trim_errors

If set to a number, and the error produced includes a line number, then only that number of lines before and after the broken line itself will be displayed, instead of the whole block.