Execute perl script using mason template - perl

I have installed Mason module from cpan. Now i am executing my first program using mason template.
first_mason.mc
% my $name = "Mason";
Hello world! Welcome to <% $name %>.
first_mason.pl
#!/usr/local/bin/perl
use Mason;
my $mason = Mason->new(comp_root => '...');
print $mason->run('first_mason.mc')->output;
This throws an error as follows
first_mason.mc is not an absolute path at C:/Perl/site/lib/Mason/Request.pm line 256**
Note
I am placing both files in the path where mason is installed(to find an installation path ,i used perldoc -l Mason) and executed a program using perl first_mason.pl

There is no need to put your files in the directory where Mason is installed:
Perl should know where to find Mason when you import it with use (assuming your perl installation is correct).
Mason will know where to find the .mc file via the comp_root argument.
The component name needs to be specified as a path relative to comp_root, always beginning with /.
You need to leave out the .mc from the component name.
So, if you place the 2 files in your home directory, then the script should look like this:
#!/usr/local/bin/perl
use Mason;
my $mason = Mason->new(comp_root => $HOME_DIR); # where $HOME_DIR is `C:\User\your_name`
print $mason->run('/first_mason')->output;
From the documentation:
The component root and component paths
When you use Mason, you specify a component root that all component
files live under. Thereafter, any component will be referred to by its
virtual path relative to the root, rather than its full filename.
For example, if the component root is '/opt/web/comps', then the
component path '/foo/bar.mc' refers to the file
'/opt/web/comps/foo/bar.mc'.

#stevenl fully answers your question. Simply don't blindly copy the Synopsis from the Mason docs, need read the docs too. :) E.g. in the example code:
#!/usr/local/bin/perl
use Mason;
my $mason = Mason->new(comp_root => '...');
print $mason->run('/foo')->output;
you need replace
and the shebang line #!/usr/local/bin/perl with the real path to your perl interpreter
the '...' with the real path in the filesystem, where your component are, e.g.
comp_root => '/some/real/path/here/where/my/component/root/is'
However, I wrote this answer mainly with a reason: if you want use the Mason for the web-app development, check the Poet module too. It GREATLY simplifies the whole process, and you will not need care about many-many things. E.g. after installing the Poet you can simply:
poet new MyApp
myapp/bin/run.pl
and you will immediately get (without any configuration) an WORKING web-app, and you could access it in your browser at http://localhost:5000. Your component_root will be inside of the myapp directory as myapp/comps.

Related

FInding relative path in Perl

I have the following code in a perl module,
package Foo;
our $pathToScript = "/home/Lucas/project841/python_script.py";
It is frequently called by other modules in the same file directory through
$output = `$Foo::pathToScript`;
# etc
I would like to remove the hard coding of the actual path and use relative path, Eg. ./python_script.py to call the script from other modules.
What would be the ideal way?
You said your Perl script is "frequently" called from the same directory where the Python script resides, not "always". If you remove the absolute path, you'll need to change that "frequently" to "always", and just change $pathToScript to the Python script name (no path).
You could also consider setting the environment PATH (in the Perl script) so that the Python script (without the full path in $pathToScript) is always found, regardless of where the user is running from or where the Perl script is located.

file for saving cookie data not found when using HTTP::Cookies in Perl script

all. I had some questions about the Perl module HTTP::Cookies. The example on CPAN is like below:
$cookie_jar = HTTP::Cookies->new( file => '$ENV{\'HOME\'}/lwp_cookies.dat', autosave => 1);
The lwp_cookies.dat file is used to save cookie data on my local machine as I understand. On my machine, '$ENV{\'HOME\'}' is an empty path. The script runs good, even after execution I can't find any file named "lwp_cookies.dat" on my machine. I changed '$ENV{\'HOME\'}' to '$ENV{\'TMP\'}', which is a path really exists after I verified by Perl print. Still I can't find the "lwp_cookies.dat" in my TEMP folder. My first question is how the HTTP::Cookies is working with the "lwp_cookies.dat" file.
On the other hand, on one of my systems(all're Windows system as mentioned here), the same code produce error message below:
Can't open $ENV{'HOME'}/lwp_cookies.dat: No such file or directory
So it's strange to me. On my good system, even file or path not exists, the script runs well, which I suppose the file is created on some temp memory instead; on bad system, the code example doesn't work at all.
If you want the $ENV{'HOME'} variable to interpolate into the string, you need double quotes; single quotes don't interpolate variables:
`file => "$ENV{'HOME'}/lwp_cookies.dat",`

Sphinx variables

I have a lot of filenames in my Sphinx config with name like /home/ubuntu/sites/sitename.dev/data/sphinx/searchd.pid with same path prefix.
Can I separate path /home/ubuntu/sites/sitename.dev/data/sphinx/ from that filename into variable to use it like $path/searchd.pid?
Its a little known feature, but the config file can actully be a script - such as PHP, perl or even plain old bash. Just uses a classic shebang line - if the first line begins with #! that intpreter is used to execute the script, and the output used as the conf file.
Example for PHP..
#!/usr/bin/php
<?php
$path = "/home/ubuntu/sites/sitename.dev/";
?>
searchd {
pid_file = <?php echo $path; ?>/searchd.pid
}
As a side note why are you having multiple pid files? Surely its best to have one single pid file - ie one single instance of searchd. A single instance can serve many indexes.
You can use this scripting capablity, to keep seperate 'files' for each index (for easy of use) - which the script consolidates into one file for use.

How to handle this situatiuon in Perl

I am having a configuration INI file to store all configuration required for my script to run. I have a Logger.PM which uses Log4Perl, and ConfigReader.PM which reads the INI file and stores the value in global variable. My Start.PL is the entry point where i call the methods from Logger and configreader.
What I do currently
In Start.PL I hardcoded the INI file path
In Logger.Pm I harcoded the directory name where log files should be stored
What I want
I want the INI file path as configurable
I want the log folder path to be taken from the INI file
I could do this by following
Pass the INI file path as a parameter to the start.pl
Read the INI file and get the folder path from INI file
What I could face is that
I cannot use the Logger.PM in ConfigReader (partially) since the
folder name required for logger is part of INI file
I want to log every step of my script (for logging/debugging purpose in case of failure. )
I can use print but this will write to console and to capture i need to use >>log.txt. Then i will be forced to maintain 2 logs for my application which is not what I wanted
Anyone have a good solution for this scenario?
You can pass INI file path in command line using Getopt::Long, and command line switches for istance:
Start.pl --ini=/path/to/INI_file
Here is a code sample to show what changes are needed in Start.pl, in order to have switches:
#!/usr/bin/env perl
use v5.12;
use strict;
use Getopt::Long;
# That little tiny 's' after 'ini=' is for string
GetOptions ( 'ini=s' => \my $ini_file );
say $ini_file;
After this change, you can read all options from your INI file, including log folder path ( are you already using a module to manage INI files like Config::IniFiles? ).
There is something still unclear in your question about print: although one of my master said that print with a pair of square brackets is the best debugger in the world, why use print when you have set up Log::Log4perl?
When you say that Logger.PL can't be used in ConfigReader, are you referring to the log object?

What is $ENV{DOCUMENT_ROOT} equivalent in perl CGI on Windows IIS (2003)

I'm migrating a perl cgi script from linux to windows IIS server 2003 and see that there is no DOCUMENT_ROOT environment variable.
Some googling suggests I can hack it by stripping stuff off the end of $0 or cwd, but getting the site root should be a common task. Is there a better or standard way of doing this?
IIS doesn't really have the notion of a document root in the same way with IIS, as each application is more or less self-contained and independent. For any request, PATH_TRANSLATED is usually a good base on which to build, it is set to the physical path name for the handling component set in PATH_INFO, and from that you can usually get to the file system locations using a little File::Spec navigation.
There's also a SCRIPT_TRANSLATED and SCRIPT_NAME, which may be closer to what you need. SCRIPT_NAME is essentially the host absolute URL (minus the scheme, host, and port) for script, and SCRIPT_TRANSLATED is the corresponding physical file. I use the URI and URI::file classes, and methods to manipulate them, for some of these tasks.
These will only be useful if your request is handled by the same application that serves files, but they do allow you do derive URLs which work. If you need the file system for the root application, the one mapped to "/", and your script is not in the same root application, you will likely have to do some accesses to the IIS metabase (essentially the equivalent to httpd.conf and friends, but queryable) to find this out.
You can print out all ENV variables with a simple CGI script, like this:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
foreach $key (keys %ENV) {
print "$key --> $ENV{$key}<br>";
}
From that output, it should be semi-obvious what the variable you're looking for is.