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.

Post a new question!

User Questions
Best way to track an error string in module?
2 direct replies — Read more / Contribute
by linxdev
on Mar 04, 2021 at 14:56
    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("", .....); $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.
4 direct replies — Read more / Contribute
by Schmunzie
on Mar 04, 2021 at 08:15
    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
Problem filling Excel cells with Solid Colour
1 direct reply — Read more / Contribute
by merrymonk
on Mar 03, 2021 at 05:29
    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?
    use strict "vars"; use OLE; use Win32::OLE::Const "Microsoft Excel"; sub RGB ($$$$) { my ($jr, $jg, $jb, $ret_c) =@_; $$ret_c = $jr + $jg * 256 + $jb *256** 2; } my ($excel, $workbook, $sheet, $rng, $jh); my ($jr, $jg, $jb, $patterncolour, $jq, $jqa); my %cell_interior_pattern; # list from https://docs.microsoft.com/en-us/office/vba/api/Excel.XlPa +ttern $cell_interior_pattern{1} = xlPatternAutomatic; $cell_interior_pattern{2} = xlPatternChecker; $cell_interior_pattern{3} = xlPatternCrissCross; $cell_interior_pattern{4} = xlPatternDown; $cell_interior_pattern{5} = xlPatternGray16; $cell_interior_pattern{6} = xlPatternGray25; $cell_interior_pattern{7} = xlPatternGray50; $cell_interior_pattern{8} = xlPatternGray75; $cell_interior_pattern{9} = xlPatternGray8; $cell_interior_pattern{10}= xlPatternGrid; $cell_interior_pattern{11}= xlPatternHorizontal; $cell_interior_pattern{12}= xlPatternLightDown; $cell_interior_pattern{13}= xlPatternLightHorizontal; $cell_interior_pattern{14}= xlPatternLightUp; $cell_interior_pattern{15}= xlPatternLightVertical; $cell_interior_pattern{16}= xlPatternNone; $cell_interior_pattern{17}= xlPatternSemiGray75; $cell_interior_pattern{18}= xlPatternSolid; $cell_interior_pattern{19}= xlPatternUp; $cell_interior_pattern{20}= xlPatternVertical; $excel = CreateObject OLE "Excel.Application"; $excel -> {Visible} = 1; $workbook = $excel -> Workbooks -> Add; $sheet = $workbook -> Worksheets("Sheet1"); $sheet -> Activate; $sheet -> Range('C2') -> {Value} = 'Index'; $sheet -> Range('D2') -> {Value} = 'Colour'; $sheet -> Range('E2') -> {Value} = 'Value of array index'; $jr = 120; $jg = 140; $jb = 55; RGB($jr, $jg, $jb, \$patterncolour); for $jq (sort {$a <=> $b} keys %cell_interior_pattern) { $jqa = $jq + 2; $rng = 'D' . $jqa; $sheet->Range($rng)->Interior -> {PatternColor} = $patternco +lour; $sheet->Range($rng)->Interior -> {Pattern} = $cell_interior_ +pattern{$jq}; $rng = 'E' . $jqa; $sheet -> Range($rng) -> {Value} = $cell_interior_pattern{$jq}; $rng = 'c' . $jqa; $sheet -> Range($rng) -> {Value} = $jq; }
How to use Plack::Middleware::Static
1 direct reply — Read more / Contribute
by vhein79
on Mar 03, 2021 at 05:11

    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 could treat every single file in my $app1, but I think configuring that with Plack should be possible.

Insert into mysql database
4 direct replies — Read more / Contribute
by NorCal12
on Mar 02, 2021 at 17:21


    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;

    Is this old Perl and not compatible with the newer version of MYSQL?

    All worked well prior to the migration.


log4perl help
1 direct reply — Read more / Contribute
by drohr
on Mar 02, 2021 at 15:31
    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:
    https://metacpan.org/pod/Log::Log4perl https://www.perl.com/pub/2002/09/11/log4perl.html/ https://www.perlmonks.org/?node_id=1198853
    but I cannot find a combination that works. Lets say I have this:
    use Log::Log4perl; sub init() { Log::Log4perl->easy_init( { level => $DEBUG, file => ">>test.log", category => "FILE" }, { level => $DEBUG, file => "STDOUT", category => "STDOUT" } ); } sub getLogger { my ($category) = @_; my $logger = Log::Log4perl->get_logger($category); return $logger; } init(); my $stdout_logger = getLogger(STDOUT); $stdout_logger->info("testing stdout logger"); my $file_logger = getLogger(FILE); $file_logger->info("testing file logger");
    How do I then change the level and file for each of these appenders? I have tried these example:
    Log::Log4perl::Logger::APPENDER_BY_NAME{'STDOUT'}->threshold($TRACE); Log::Log4perl->appender_by_name('STDOUT')->threshold($TRACE);
    but they did not work. Alternatively, I tried this example:
    https://metacpan.org/pod/Log::Log4perl#Advanced-configuration-within-P +erl
    and I got the logging to work, but I could not change the appender. What am I missing or doing wrong? Thanks

    -- UPDATE --


    Here is how you change the file in an appender at run time:

    <code> Log::Log4perl->appender_by_name('FILE')->file_switch('test2.log'); <code>
Use of do() to run lots of perl scripts
8 direct replies — Read more / Contribute
by chrestomanci
on Mar 02, 2021 at 12:34

    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.

    I searched online and found the do builtin in perl and this article about it.

    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.

Looking for alternative syntax for assigning variables based on regex matches
4 direct replies — Read more / Contribute
by thirtySeven
on Mar 02, 2021 at 00:07
    I have settled into using this syntax for assigning variables based on regex matches.
    $foo = $1 if $foo =~ /(hello)/;
    I am constantly doing this so I want to know other ways to do the same thing.
Adding to legacy application: does it make sense to use PSGI in CGI mode
6 direct replies — Read more / Contribute
by hotpelmen
on Mar 01, 2021 at 22:07

    Hello Monks,

    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?

    Thank you!

PAR pp error when executing created file
4 direct replies — Read more / Contribute
by g_speran
on Mar 01, 2021 at 19:58
    Hello Perl Monk....I seek your wisdom I am trying to use pp to package a file and a script into a file called iDPAswitch.exe the command I use is:
    pp -o iDPAswitch.exe -a #iDPA_SW_Template220 iDPAswitch-2_3_0.pl
    it seems to package fine until I execute th iDPAswitch.exe file. I get the below error
    error: member not found at script/main.pl line 26. Extract of iDPAswitch.exe failed
    I have tried altering the syntax as follows to include non-core modules & core modules needed
    pp -o -B iDPAswitch.exe -a #iDPA_SW_Template220 iDPAswitch-2_3_0.pl
    I get the same "member not found error". I have opened iDPAswitch.exe with 7-zip and confirmed that iDPAswitch-2_3_0.pl is in the scripts directory and the Template file included is one level up/back The contents of main.pl are as follows
    if (defined $ENV{PAR_APP_REUSE}) { warn "Executable was created without the --reusable option. See 'p +erldoc pp'.\n"; exit(1); } my $zip = $PAR::LibCache{$ENV{PAR_PROGNAME}} || Archive::Zip->new(__FI +LE__); my $member = eval { $zip->memberNamed('script/iDPAswitch-2_3_0.pl') } or die qq(main.pl: Can't open perl script "script/iDPAswitch-2 +_3_0.pl": No such file or directory ($zip)); # Remove everything but PAR hooks from @INC my %keep = ( \&PAR::find_par => 1, \&PAR::find_par_last => 1, ); my $par_temp_dir = File::Spec->catdir( $ENV{PAR_TEMP} ); @INC = grep { exists($keep{$_}) or $_ =~ /^\Q$par_temp_dir\E/; } @INC; PAR::_run_member($member, 1);
    How can I identify what "member not found" its failing on and how to rectify it

    Thanks in Advance....

Add your question
Your question:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.