http://www.perlmonks.org?node_id=479

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
Help with WKHTMLTOPDF
3 direct replies — Read more / Contribute
by justin423
on Dec 07, 2023 at 18:24
    Can't figure out how to use WKHTMLTOPDF and getting a hash error

    Here is the code with 3 different methods, but none work and seem to be relating to what is surrounding the filenames

    use WKHTMLTOPDF; $filename='test.html'; $path='/temp/'; $inputfile="$path$filename"; $outputfilename='TEST'; $ext='.pdf'; $outputfile="$path$outputfilename$ext"; my $pdf = new WKHTMLTOPDF; $pdf->_input_file('/temp/TEST.html'); $pdf->_output_file('/temp/TEST.pdf'); $pdf->_input_file('$inputfile'); $pdf->_output_file('$outputfile'); $pdf->grayscale(1); $pdf->generate; #system ("cd C:\Program Files\wkhtmltopdf\bin"); #system ('start "C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf $inputfi +le $outputfile"'); #system ('start "C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf /temp/TE +ST.html /temp/TEST.pdf"');

    Here is the error message

    couldn't find command '/usr/bin/wkhtmltopdf' at C:/Strawberry/perl/sit +e/lib/MooseX/Role/Cmd.pm line 117. MooseX::Role::Cmd::run(WKHTMLTOPDF=HASH(0x6759d0), "/temp/TEST +.html", "/temp/TEST.pdf") called at C:/Strawberry/perl/site/lib/WKHTM +LTOPDF.pm line 645 WKHTMLTOPDF::generate(WKHTMLTOPDF=HASH(0x6759d0)) called at ht +mlpdf.pl line 15
On Windows I am trying to run a perl JDBC script, but am running into the error Expecting tag 0x73875f
2 direct replies — Read more / Contribute
by mallett76
on Dec 06, 2023 at 11:36

    Hello, I am trying to run a perl JDBC script, but am running into the error:

    DBI connect('hostname=172.28.130.20;port=1025;url=jdbc:teradata://172.28.130.20/;databaseName=NDW_JRNL_VIEWS','pMalle001',...) failed: Expecting tag 0x73875f, found 0x3 at C:/Strawberry/perl/site/lib/Convert/BER.pm line 379. ...propagated at C:/Strawberry/perl/site/lib/Convert/BER.pm line 798. at JDBC-ConnectionTestNewNewest.pl line 15. Database connection error: Expecting tag 0x73875f, found 0x3 at C:/Strawberry/perl/site/lib/Convert/BER.pm line 379. ...propagated at C:/Strawberry/perl/site/lib/Convert/BER.pm line 798.

    Here is my code:

    use DBI; use JDBC; $user="xxxx"; $password="xxxx"; $url = "jdbc:teradata://172.28.130.20/;databaseName=NED_BASE_VIEWS"; $url =~ s/([=;])/uc sprintf("%%%02x",ord($1))/eg; print $url; $dbh = DBI->connect("dbi:JDBC:hostname=172.28.130.20;port=1025;url=jdb +c:teradata://172.28.130.20/;databaseName=NDW_JRNL_VIEWS", $user, $pas +sword);
Why does each() always re-evaluate its argument?
4 direct replies — Read more / Contribute
by Darkwing
on Dec 06, 2023 at 07:35

    Hi Monks,

    During development, I noticed a behavior of eval that I had not expected

    use strict; use warnings; my %h = (a => 1, b => 2, c => 3); sub clone_h { print "cloning \%a\n"; return +{%h}; } while (my ($key, $val) = each(%{clone_h()})) { print("$key => $val\n"); }
    This results in an infinite loop, printing
    cloning %a b => 2 cloning %a c => 3 cloning %a a => 1 cloning %a c => 3 cloning %a a => 1 cloning %a a => 1 cloning %a b => 2 cloning %a c => 3 ...

    Obviously, clone_h() is called again and again. Of course, I can work around this by first saving the result of clone_h() in a temp variable and then put the variable into the each(). But why does each() not just evaluate its argument and then work on the result?

    I tried this with perl 5.10, 5.14 and 5.38.

    But: The corresponding code using an array and foreach() works as expected:

    use strict; use warnings; my @a = qw(a b c); sub clone_a { print "cloning \@a\n"; return [@a]; } foreach my $entry (@{clone_a()}) { print "$entry\n"; }

    Why does each (but not foreach) it work like that? Why is a temporary variable forced (which seems redundant to me)?

    2023-12-06 Retitled by Discipulus, as per Monastery guidelines
    Original title: 'Why does eval() always re-evaluate its argument?'

Character encoding in emails
8 direct replies — Read more / Contribute
by Bod
on Dec 05, 2023 at 16:59

    I have two email-sending processes. Both are seemingly the same but they produce different results. Both use MIME::Lite.

    One sends emails immediately, the other is for larger numbers of emails and consists of an email queue held in a MariaDB database. The sending script runs every 20 minutes from CRON. The body text for both gets to them from an HTML textarea and they have been tested using identical body text.

    If we add an emoji character to the body text, the queue sends it correctly. But the immediate sending script produces ��� instead of the emoji.

    As far as I can tell the only differences between the scripts is that one runs under CRON and stores and retrieves the body using a database. Other than that they seem identical.

    Both scripts use utf8;

    I am at a loss how to debug the problem...what would you try to get to the root of this problem?

Archive::Zip: save entire directory?
2 direct replies — Read more / Contribute
by Anonymous Monk
on Dec 05, 2023 at 16:26

    I'm trying to do what I thought would be a very simple task: Create a zipfile with the contents of an entire directory, passed in to a function. I wrote (with very minor changes from the real code):

    sub create_zipfile { my ($path) = @_; my $UUID = Data::GUID->new->as_string(); my $zipfile_name = $UUID . ".zip"; my $full_path = $path . "/" . $zipfile_name; my $zip = Archive::Zip->new(); $zip->addTree($path, undef); if ( ! $zip->writeToFileNamed($full_path) == AZ_OK ) { print "Error writing zipfile: $!\n"; } return $full_path; }
    I tried to run this as "my $filename = create_zipfile("/path/to/directory");", and it fails with IO error: Can't open /path/to/directory/0BE30138-93B4-81EE-93CD-DC592DB8B6F0.zip for write : No such file or directory. Which--I know there's no such file or directory, I'm asking it to be created.

    In a previous version of this--and I don't remember what's different, and can't replicate it--it did create a zipfile, but it was empty.

    I'd be grateful for a pointer; this would seem to be the main way one would use this module, but I can't find discussion of how to do this! Thanks.
SOAP::Lite - how to remove namespaces
1 direct reply — Read more / Contribute
by ffrost
on Dec 05, 2023 at 11:29

    I have code where I've supplied a snippet of the relevant parts below:

    $soap = SOAP::Lite ->proxy($proxy) ->uri($uri) ->autotype(0) ->ns('http://www.w3.org/2003/05/soap-envelope','soap') ->ns('http://mil.dod.af.A1.personnel.dataservices.filter','mil') ->ns('http://mil.dod.af.A1.personnel.dataservices.training/v2.4','v2') ->readable(1);

    This creates the following output:

    <soap:Envelope soap:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ xmlns:mil=http://mil.dod.af.A1.personnel.dataservices.filter xmlns:soap=http://www.w3.org/2003/05/soap-envelope xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding/ xmlns:v2=http://mil.dod.af.A1.personnel.dataservices.training/v2.4 xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance>

    But I need it to look like this, without the magically included namespaces:

    <soap:Envelope xmlns:mil=http://mil.dod.af.A1.personnel.dataservices.filter xmlns:v2=http://mil.dod.af.A1.personnel.dataservices.training/v2.4 xmlns:soap=http://www.w3.org/2003/05/soap-envelope>

    How do I get rid of the soap:encodingStyle, xmlns:soapenc, xmlns:xsd and xmlns:xsi namespaces? If I use these extra namespaces in the web service call then it fails their validation check.

Spreadsheet::ParseXLSX returning zero
2 direct replies — Read more / Contribute
by bitingduck
on Dec 05, 2023 at 02:14

    Fellow monks, I have a problem that isn't necessarily a Perl problem, so much as it manifests itself when I'm using Perl, and I'm hoping that there may be a relatively painless Perl solution.

    For many years I've been getting monthly data files in Excel from a little company in Seattle. For years I've parsed them into a database, using first Spreadsheet::ParseExcel, then as the format changed using Spreadsheet::XLSX, and more recently using Spreadsheet::ParseXLSX. And despite the changes from .xls to .xlsx and a few format changes, things have been mostly good.

    Some time around a year ago the format didn't change, but the Spreadsheet::ParseXLSX stopped reading the file correctly. Or maybe more accurately, whoever wrote the file stopped writing it correctly, and now Spreadsheet::ParseXLSX doesn't read it correctly. The particular issue where it first manifests is in reading a cell with "Month Year" in the contents (e.g. "December 2023"). When I read the cell with

     my $mycell=$worksheet->get_cell();

    and then try to evaluate it with either

    my $value=$mycell->value(); # or my $unformatted=$mycell->unformatted();

    it returns "0" or "0.0" respectively. The catch is that if I simply open the file in Excel and hit "save", or open it in Apple's Numbers and export it back to XLSX, it then parses correctly, like it always used to. So the Excel file opener is fairly forgiving of whatever changed, but Spreadsheet::ParseXLSX isn't, and I don't see an obvious way to get at the content to debug. Using Data::Dumper on $mycell also shows zeros where it should give the month and year. I haven't tried other cells - once it barfs, I remember I have to open/save and that presumably fixes all the cells.

    This is something I can live with if I have to, since I only have to deal with the files a few times a year and can just open/save them quickly, but it seems so wrong. I'm not sure it's a widespread problem - someone else is writing the file using a program other than Excel so I can read it with a program other than Excel. The smart thing would be if the generator produced CSV, but that's not something I can influence.

XS Modules - why and when?
8 direct replies — Read more / Contribute
by Bod
on Dec 04, 2023 at 19:22

    I know little about XS modules but I was looking at RPi::DHT11 and noticed that it is an XS module which seemed a little strange. Hence the question here. I was going to email stevieb, the author and ask but thought it would be good to get other people's take on this.

    My understanding of an XS module is that it uses XSLoader to load C / C++ / C# code. The Perl is just a wrapper around the loaded code with the Perl doing little processing. I believe the main reason to do this is for speed as compiled languages of the C family are faster than interpreted languages such as Perl. Is that about right so far?

    Assuming that is something like correct...
    Why would the RPi::DHT11 module use XS? The DHT11 is a temperature and humidity sensor with a maximum frequency of 0.5Hz (one read per 2 seconds). So speed is not the issue here!

    What reason would there be for creating an XS module in this use case? Would it not be easier and simpler and just as fast given the speed of the sensor, to write all the code in Perl?

    I'm hoping for more insights into the world of XS modules here...

How to create and install a module compatible with both UTF8 and Perl 5.8.3 without using non-core modules?
2 direct replies — Read more / Contribute
by Polyglot
on Dec 02, 2023 at 12:04
    My attempt at launching my module belly-flopped. I've learned that even though Test::More is part of Perl core going back to v5.6.2, Test::More::UTF8 was never part of Perl's core. Furthermore, Test2, said to be unicode compatible, only made it to core in Perl 5.25.1.

    My module does not need to use unicode. If the unicode comments and POD were stripped out of it, it would not even require "use utf8;" as there is no unicode in its actual code. But because it is for utf8 and the tests, to be meaningful, incorporate uft8 characters, the entire module fails to install on perl systems which do not already have the non-core module "Test::More::UTF8."

    In order to make the installation as easy and fuss-free as possible, and more space-conserving, too, I don't want to require the installation of non-core modules. If there is not a better way to do this, my next version release will abandon all of those useful tests and put in one or more tests which require no unicode at all--just a "free pass" so to speak. This way, at least, the install would be able to complete.

    So the question remains, is it even possible to create, and install, a module designed for Perl 5.8.3 compatibility, that provides UTF8 functions, and that does not require any non-core modules--and do this with reasonable UTF8-based tests?


    UPDATE:

    I think I've managed to find a hackish solution that should get me by for now. I've dumped once again (I should not have gone back to it after dropping it the first time) the "Test::More::UTF8" package earlier thought to be a "solution" for the lack of UTF8 compatibility of Test::More...it wasn't, and even when the package was manually installed (not part of core), it tended to generate some inexplicable 'wide character' warnings. So, I went with a pure-ASCII solution, no need even for "use utf8" in the testing script. Instead of testing on actual UTF8 characters, the script now tests on the hexadecimal codepoints returned from the module. If the correct codepoint is returned, the function can legitimately be considered to be installed and functioning. It would have been nice to test on real unicode, but oh well...the module will still work just fine, I'm sure.

    Blessings,

    ~Polyglot~

Converting Unicode
4 direct replies — Read more / Contribute
by BernieC
on Dec 01, 2023 at 18:20
    I can't get unicode to work. I have a file that , mixed in with regular text, there are the unicode characters for open quote, close quote and apostrophe. i've been trying to write a little program to replace them with non-unicode characters {" " and ,}. I've tried this test program
    these are the constants from cryptfix # use constant APOSTROPHE => "’" ; # use constant OPENQUOTE => "“" ; # use constant CLOSEQUOTE => "”" ; # use constant COMMA => "¸" ; # This is the version from a hex dump of the crypt text file use constant APOSTROPHE => "\x{e2}\x{80}\x{22}" ; use constant OPENQUOTE => "\x{e2}\x{80}\x{90}" ; use constant CLOSEQUOTE => "\x{e2}\x{80}\x{9d}" ; use constant COMMA => "¸" ; unless (@ARGV) { die "usage: <crypts-text-file>\n" ; } open(CRYPTS, "<", $ARGV[0]) or die "Can't open $ARGV[0]: $!" ; while (my $line = <CRYPTS>) { say "apostrophe in line $." if $line =~ /@{[APOSTROPHE]}/; say "open quote in line $." if $line =~ /@{[OPENQUOTE]}/; say "close quote in line $." if $line =~ /@{[CLOSEQUOTE]}/; }
    and I feed it the text file with the unicode characters in it and it never finds any. I'm not sure what I'm getting wrong.

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