If
you have a question on how to do something in Perl, or
you need a Perl solution to an actual real-life problem, or
you're unsure why something you've tried just isn't working...
then this section is the place to ask.
However, you might consider asking in the chatterbox first (if you're a
registered user). The response time tends to be quicker, and if it turns
out that the problem/solutions are too much for the cb to handle, the
kind monks will be sure to direct you here.
PS: Hey Mike can't wait to hear about your huge "expertise" from JAVA, bread-trucks and millions of lines of PHP ...
UPDATE
2 monks msged me Where does $OBJ come from?
In this simplified example you can consider it a global, like
our $OBJ = SomeClass->new();
The real use case is a more complicated implementation of a with construct (like in with), where $OBJ is a closure var and AUTOLOAD is localized to a blocks context.
I have written a number of modules that make use of storing an error string to be called by the caller for retrieval. I am running my code through Perl::Critic and I think I need to refactor this idea to make it more "The Right Way(tm)." Below is some pseudo code with some sample methods.
package Object;
sub new {
my $class = shift;
my $self = { 'ERRSTR' => undef };
bless $self, $class;
return $self;
}
sub _errstr {
return $_[0]->{'ERRSTR'};
}
sub _login {
my $self = shift;
eval {
...
$self->{'CONNECTION'} = ....
};
if($@) {
$self->{'ERRSTR'} = $@;
return 1;
}
return 1;
}
sub _ping {
my $self = shift;
eval {
if(not $self->{'CONNECTION'}) {
$self->login() or die $self->errstr();
}
....
};
if($@) {
$Self->{'ERRSTR'} = $@;
return 0;
}
return 1;
}
# This allows me to control nesting so that debug statements are inden
+ted by 1 space so that
# I can easily see the flow if I call Object->set_debug(1) from the ap
+plication.
AUTOLOAD {
our $AUTOLOAD;
my $request = undef;
my $funcs = {
'ping' => sub { _ping(@_); },
..
};
if($AUTOLOAD =~ m/^Object::(.+?)$/) {
$request = $1;
foreach my $ref (keys %{ $funcs }) {
next unless $ref eq $request;
... increment debug indention ...
my $val = $funcs->{$ref}->($@);
... decrement debug indention ....
return $val;
}
}
die "Method ${AUTOLOAD} does not exist."
}
Many methods call other object methods as needed. This particular module
use SOAP::Lite to connect to a web server. I've abstracted all SOAP code from
the application and reduced it to something like this:
use Object.
sub main {
eval {
my $service = Object->new("127.0.0.1", .....);
$service->ping() or die $service->errstr();
};
if($@) {
warn "$@";
return 1;
}
return 0;
}
exit main;
Every time I want the application to be as few lines as possible and simple I'll write a module that will
abstract the real module and do maintenance tasks. I do this most often with DBI where I'll target a SQLite file.
The application will call methods that will manipulate data in the database. The module will check the integrity of the db, create it if it does not exist, vacuum if needed, etc.
I use the same module with $self->{'ERRSTR'}
As I convert the die() to croak() in Object I'm concerned that my method of writing the object is not compatible with Carp's stacktrace.
Dear Wise Monks,
I use CGI::Carp to view errors in the web browser during development. In production, I would like to divert STDERR to a logfile. I after bright ideas for an efficient and reliable way of switching between the two.
Thanks
I want to fill the background of excel cells with colours made up from the known red, green and blue components of the colours. To do this I found I needed to use:
$sheet->Range($rng)->Interior -> {PatternColor} = rgb colour value
$sheet->Range($rng)->Interior -> {Pattern} = pattern value
This site https://docs.microsoft.com/en-us/office/vba/api/Excel.XlPattern gives ‘values’ for 20 patterns including xlPatternSolid which I thought would give me the whole cell filled with that colour. This was not the case as the Perl below shows.
This code gives an Excel spreadsheet where:
Column C is the key to a hash which holds the pattern ‘names’ such as xlPatternSolid
Column D gives the cell filled with the colour and effect of the pattern
Column E gives the value of the pattern ‘names’ as shown on the web-site.
Cell D20 is where the xlPatternSolid has been used. This has no colour instead of the solid colour I was hoping for. Also cell D3 has no colour – the name of this colour pattern xlPatternAutomatic – I was not sure what to expect for this.
I did notice that the sides of cells D20 and D3 are no longer there.
How can I get cells filled with the solid colour?
I run a website, changing now from FCGI to PSGI using Plack as server.
The behaviour should be the same as with the old Apache website,
(which I configured with .htaccess files for each directory) so I want to
use js when it is needed, and show it as text/plain when someone clicks such a non binary file in my download directory.
I don't want to use dancer etc now, because I had to make big changes to the website then (FCGI and PSGI are quite similar to use).
I tested a bit and the behaviour seems to be version dependent (on Windows it works, on CentOS not),
but I want a safe way using different Plack::MIME instances for different directories.
What I have now uses the same Plack::MIME instance and doesn't work correctly when I include .html, .css etc there:
use Plack::Builder;
use Plack::MIME;
# normal behaviour /html/
# special behaviour /html/downloads/
for my $expr (
".c", ".cpp",".csv", ".dat", ".dpl"
, ".gp", ".h", ".hpp", ".ini"
, ".java", "makefile", ".m", ".mac"
, ".pl", ".pm", ".pod", ".py"
, "README", ".sch", ".sh", ".txt") {
Plack::MIME->add_type($expr => 'text/plain');
}
builder {
enable 'Plack::Middleware::Static',
path => qr{/html/}, root => '.';
# normal behaviour:
# needs a new content_type instance! how doing this?
# enable 'Plack::Middleware::Static',
# path => qr{^/html/(?!downloads).*\.
# (css|gif|jpg|js|pdf|png)$}, root => '.';
mount "/" => $app1;
mount "/imggenerator.pl" => $app2;
};
I have a website written in Perl and operating out of cgi-bin. It has been up and running fine for the past 10 years. My site is an auction for commercial fishermen that allows them to buy and sell quota (fishery management). Sales data has been transferred into a MYSQL database.
This past weekend the folks that run the server told me that my version of Cpanel need to be updated, but the new version would not run on the server that I was on, so they would migrate me to another server. So I got migrated. The new server runs a newer version of PHP (version 7.X) and MYSQL.
And now I receive an error message when sales are attempting to be added to the database. The Error message occurs at the "execute" command.
Here is the relevant section of code:
##### prepare and execute query
my $query = "INSERT INTO closedauctions (seller, sellerusername, categ
+ory, title, bids, pounds, description, winningbid, price_per_pound, h
+ighbidder, buyerusername, month, day, year, itemnum, filename) VALUES
+(\"$sellername\",\"$sellerusername\",\"$quota\", \"$category\", 1, \"
+$pounds\", \"$desc\", \"$buyit\", \"$price_per_pound\", \"$buyername\
+",\"$buyerusername\", \"$month\", \"$day\", \"$year\", \"$form{'ITEM'
+}\", \"$cat\")";
my $sth = $dbh->prepare($query) || die "Could not prepare SQL statemen
+t ... maybe invalid?";
$sth->execute() || die "Could not execute SQL statement ... maybe inva
+lid?";
##### disconnect from database
$dbh->disconnect;
Hello,
I am trying to setup a logger that has multiple appenders/categories (for example, one that goes to a file and one that goes to stdout). However, I also need to be able to modify the appenders after the initialization. For example, I want to update the log level and update the file name after initialization. I have found several examples of how to create the logger (and I have been successful in creating and using them), but I cannot figure out how to modify the appenders.
I have worked through the documentation and help on these sites:
I am working on an legacy perl application that frequently invokes other perl scripts. The application runs as a server, and in response to each remote connection it does a fork and the child invokes another worker script via a system call. Most but not all of these scripts are perl.
There are about 500 perl scripts that could be run, and most are trivial. The volume of incoming connections is high, and the application has performance issues, which I suspect are in part caused by the overhead of invoking a fresh perl interpreter for each of these trivial scripts.
Would it make sense to modify my application so that worker perl scripts are invoked via do() instead of system calls?
I am running perl 5.10 via Carton (The legacy app is not compatible with more recent perl versions due to use of Storable)
Would there be any issue with non-trivial perl scripts?
Do I need to wrapper the call to do() in an eval block or does that happen automatically?
Bear in mind that the caller of each worker script is a forked child from the main server process, so if the worker script goes wrong in some way such as leaking memory, the main server process is in the parent so should not be affected.
There are no security concerns here. All the code is trusted, and was written by company employees, so I only have to worry about mistakes, not malice.
There's a 20 yr old Perl/CGI web application that currently runs on Apache 2.4 and uses Perl 5.16. Linux box it runs on has one IP address and has no associated domain name.
It is still being actively used inside my company by a dozen of employees, and I was asked to add a new page to it (standard interaction with database and displaying of results in the browser). I may have to add a page or two again within a year or two, so looking ahead I want to use something better and newer than 'use CGI' and print.
Looks like in my situation I can't just add Dancer2-based scripts to legacy application as Dancer's routing seems to require a separate VirtualHost that I can't create in this no-domain single-IP situation. So I am thinking to use middle path: Template for HTML part of it, and I was advised to use PSGI in CGI mode for interacting with Apache instead of using CGI.pm.
Using PSFI in CGI mode looks easy to do, but I am new to it and I am trying to avoid any path that may make me regretful later. Based on your experience and wisdom, what will be the immediate benefits of using PSGI/Plack for the new page, and is there anything I should beware of? Other thoghts?