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
Zipping the contents of a directory by filename
3 direct replies — Read more / Contribute
by justin423
on May 29, 2025 at 10:55
    What am I missing? I am trying to zip a few hundred PDF's by the first 7 letters of the filename to make each zip a manageable size.

    It is zipping all of them into just one file and I know it must be something simple that I am missing.

    #!/usr/bin/perl use IO::Compress::Zip qw(:all); $path='/DATA/DOCUMENTS/'; opendir my $dh, $path; my @files = readdir $dh; foreach my $files (@files){ print "$files\n"; $zipfilename=substr($files,7); $zipfilename1=$path.$zipfilename; zip [ glob("$zipfilename1*.pdf") ] => "$zipfilename1.zip" or die "Cannot create zip file: $ZipError" ; } closedir $dh;
File::XDG on varying platforms
2 direct replies — Read more / Contribute
by Intrepid
on May 26, 2025 at 14:13

    This is going to seem like a very esoteric line of inquiry, I suspect, but I will put it out here for the fine monks and nuns to give me feedback.

    I use a computer with Windows 10 and with Cygwin installed (as I often mention on PMo). I have this computer and 5 other computers to configure for file locations under my home dir for the vim editor, meaning places to keep backup files and to keep swap files. All those 5 systems run Debian or some derivative distro of Debian Gnu/Linux. So things as they stand will be relatively predictable when I get around to configuring them. Yes, I could do this "by hand" on each system, but automating such a repetitive chore is exactly one of the compelling reasons Perl exists.

    Here are the outputs of my script using File::XDG at this stage of writing it (see the code below):

    According to File::XDG on Cygwin, the following directories would be used for "vim":
    
    Config for app vim is   C:/Users/somia/config/vim
    Data for app   vim is   C:/Users/somia/AppData/share/vim
    Cache for app  vim is   C:/Users/somia/cache/vim
    
    According to File::XDG on MSWin32, the following directories would be used for "vim":
    
    Config for app vim is   C:/Users/somia/AppData/Local/.config/vim
    Data for app   vim is   C:/Users/somia/AppData/Local/.local/share/vim
    Cache for app  vim is   C:/Users/somia/AppData/Local/.cache/vim
    
    According to File::XDG on Linux, the following directories would be used for "vim":
    
    Config for app vim is   /home/somian/.config/vim
    Data for app   vim is   /home/somian/.local/share/vim
    Cache for app  vim is   /home/somian/.cache/vim
    
    Pretty unpredictable, huh! Note in particular the distinction between the Cygwin results and the MSWin results. I could use CygwinPerl for this, or Strawberry. In the end, maybe it's basically an esthetic choice. Which looks better to you? I'm leaning towards the choice made by Strawberry (Win32) perl.

    The Code

    EDIT

    The original code I posted - unfinished, placed in READMORE tags:

    The (probably) final code

    #!/usr/bin/env perl # Last modified: Tue May 27 2025 03:02:52 PM -04:00 [EDT] use strict; use v5.18; use utf8; use warnings; =head1 SYNOPSIS perl Emplace-XDG-dirs =cut use File::XDG 1.00; use File::Spec; use File::Path qw(mkpath rmtree); use subs qw/tellMe/; my ($XDGUser, $XDGData, $XDGCache); my $appName = 'vim'; my $xdgEmp = File::XDG->new( name => $appName , api => 1 ); $XDGUser = $xdgEmp->config_home; $XDGData = $xdgEmp->data_home; $XDGCache = $xdgEmp->cache_home; my @branches = (File::Spec->catdir($XDGData => 'backups'), File::Spec->catdir($XDGData => 'swapfiles')); say "We could make these dirs for you:"; say join qq[\n]=>@branches, ''; if (tellMe("making those dirs for $appName")) { mkpath (@branches, {verbose => 'true', mode => 0775}); } else { say "No? OK, aborting now"; } =head2 Vim settings Put in our .vimrc config file: set backup set backupcopy=auto set backupdir= ... (dir created by script) set directory= ... (dir created by script) =cut sub tellMe { my $gummy = $_[0]; my $ans = "Y"; printf "Do you want proceed with: %s? [Y/n]\n", $gummy; chomp ($ans = <STDIN>); if ($ans =~/Y|y/) { return 1; } elsif ($ans eq '') { return 1; } else { return 0; } } # vim: ft=perl et sw=4 ts=4 :

    Thanks for your interest!

    May 27, 2025 at 19:04 UTC

    A just machine to make big decisions
    Programmed by fellows (and gals) with compassion and vision
    We'll be clean when their work is done
    We'll be eternally free yes, and eternally young
    Donald Fagen —> I.G.Y.
    (Slightly modified for inclusiveness)

Speed comparison of foreach vs grep + map
6 direct replies — Read more / Contribute
by mldvx4
on May 25, 2025 at 13:57

    Greetings, PerlMonks!

    I'm trying to figure out if foreach is faster than grep with map. I've replaced grep and map in a large script with foreach and noticed a substantial speed improvement, so my guess is that it is faster. However, I'd like to verify that somehow.

    With the two scripts below, am I comparing the same things and not apple to oranges? Or have I misunderstood grep and map?

    #!/usr/bin/perl use strict; use warnings; my @c = (1 .. 10000000); my @d; foreach my $dd (@c) { push(@d, $dd % 2); } my @e; foreach my $ee (@d) { if (!$ee) { push(@e, $ee); } } exit(0);

    The script above is much faster than the one below, according to time.

    #!/usr/bin/perl use strict; use warnings; my @c = (1 .. 10000000); my @d = map( $_%2, @c); my @e = grep(/0/, @d); exit(0);
Key bindings in the Debugger
1 direct reply — Read more / Contribute
by hexcoder
on May 23, 2025 at 07:28
    While debugging with StrawberryPerl when I enter a '§' character, I see that the previously entered line is deleted instead.

    x %INC shows that modules Term::Readline, Term::ReadKey and Term::Cap are loaded.

    Does anybody know, how to switch off this editing function binding?

    Thanks!

Where is plain XS.pm?
6 direct replies — Read more / Contribute
by lyman
on May 22, 2025 at 16:26
    Dear Perl Monks,

    I'm an experienced perl programmer, and am having difficulty getting the module XS-Typemap::Typemap to work. It needs an XS.pm . I have searched, searched, and pulled out a lot of hair, and I cannot find what I must install to get an XS.pm . No, it's not something::XS or XS:something, just plain XS. I have installed Debian apts

      libx11-xcb
      libx11-xcb-dev
      libx11-protocol-perl
      libx11-protocol-other-perl
      libx11-xcb-perl
      xorg-dev
      libxext-dev
      libxfexes-dev
      libx11proto-dev
      libxmu-dev
      libxmuu-dev
      libxt-dev
      xutils-dev
      libperl-dev
    
    I find on metacpan.org/search dozens of modules with "XS" in their names, but not plain XS.pm . How do I install this XS.pm, so that XS-Typemap::Typemap will work?

    Many thanks,

    Lyman

Race when redirecting output.
1 direct reply — Read more / Contribute
by gnosti
on May 21, 2025 at 17:49
    Experienced Monks!

    I have a command-line app that parses commands and prints the output to the terminal. In search of new features, I'm migrating the terminal library from readline to tickit.

    To simplify this changeover, my plan is to use open and select to direct the default output filehandle to a $variable, and then periodically dump the contents of $variable to a tickit widget.

    I'm close, but my naive implementation loses every other line of output. Seems like I need to away to ensure that writes to $command_output are held up while printing and then deleting the contained text. Some kind of first-in-last-out buffer with synchronization.

    Will be grateful for any hints on an easy way to accomplish this. Here is sample code demonstrating my conundrum:

Perl Expect Help
3 direct replies — Read more / Contribute
by Anonymous Monk
on May 21, 2025 at 16:01

    I am having a problem with understanding expect. I have am trying to create an shh script. I have 3 different conditions:

    1. host is unknown it needs to be added to known host list,
    2. host needs password,
    3. host dose not need password as it is using ssh key.

    $exp->expect($timeout, [ qr/\(yes\/no\)\?/i, sub { my $self = shift; $self->send("yes\r"); <----unk +nown host exp_continue; }], [ qr/password: /i, sub { my $self = shift; $self->send("$password\n"); <--- +--- needs password exp_continue; }], [ qr/#/i, sub { my $self = shift; <------ +-- ready to go. $self->send("ls\n"); ; }], );

    So how do I, once I get through the 3 conditions continue using expect?

    $exp->expect($timeout, [ qr/#/i, sub { my $self = shift; $self->send("ll\n"); <---- only + works when I have a line below (crazy that is how I know this is not + right) ; }], un +less ($exp->expect($timeout, -re , "~")){} ; );
    What I would like is to get past the three different ssh scenarios and keep going on.

    #!/usr/bin/env perl use strict; use warnings; use Expect; #$Expect::Exp_Internal = 1; my $command = "ssh"; my $user = "root"; my @ips = ("10.16.135.157"); my $cnt= 0+@ips; my $password = "aristo1"; my $timeout = 10; for (my $i =0; $i < $cnt; $i++) { my $exp = Expect->spawn ($command, "$user"."@"."$ips[$i]"); #$exp->debug(2); $exp->expect($timeout, [ qr/\(yes\/no\)\?/i, sub { my $self = shift; $self->send("yes\r"); exp_continue; }], [ qr/password: /i, sub { my $self = shift; $self->send("$password\n"); exp_continue; }], [ qr/#/i, sub { my $self = shift; $self->send("ls\n"); ; }], ); $exp->expect($timeout, [ qr/#/i, sub { my $self = shift; $self->send("ll\n"); ; }], ); unless ($exp->expect($timeout, -re , "~")){} ; # $exp->send("time\n"); }
PLS (Perl Language Server) renaming support in NVIM
1 direct reply — Read more / Contribute
by igoryonya
on May 21, 2025 at 04:36

    Hello, I've installed https://metacpan.org/dist/PLS module.
    Configured it in NVIM with https://github.com/neovim/nvim-lspconfig plugin.

    Auto completions work. It even shows documentation excerpts, when cursor is over some keyword or library module, but out of all issues, my biggest problem is that Language Server's renaming doesn't work.
    When I try to rename some function or a variable, it gives me an error:

    '[LSP] Rename, no matching language servers with rename capability.'

    Does anybody know, if perl Language servers don't support such functionality or did I configure something wrong?

Dancer2 App Deployment through Apache Proxy
2 direct replies — Read more / Contribute
by choroba
on May 20, 2025 at 11:53
    I wrote a Dancer2 application to be used by about 10 people from work. It ran fine on http://localhost, but the pages needed to be available from the outside world. Our IT admin told me the standard practice is to run it on a virtual host and use Apache's mod_proxy.

    Dancer2::Manual::Deployment even mentions such a possibility, so I followed the instructions. I included

    behind_proxy: 1
    to config.yml, and the admin configured the proxy similarly as shown in the manual (see Using-Apache's-mod_proxy of Dancer2::Manual::Deployment.

    I was given a prefix under which the app would be running, e.g. https://example.com/prefix/login.

    But it doesn't work correctly. For example, the css files are ignored. Or rather, they can't be found.

    The main.tt template was created with the following link (part of the initial scaffolding):

    <link rel="stylesheet" href="<% request.uri_base %>/css/style.css">

    But the request.uri_base doesn't expand to /prefix, it remains empty.

    Similarly, I use Dancer2::Plugin::Auth::Tiny for user authentication. Again, I almost copied verbatim the synopsis code:

    get '/' => needs login => sub { # ... }; get '/login' => sub { template 'login' }; post '/login' => sub { my $user = body_parameters->get('uname'); if (is_valid($user, body_parameters->get('psw'))) { session(user => $user); redirect('/') } else { template index => {error => 'Wrong username or password'} } };

    But again, when I try to open the page, the authentication plugin redirects the browser to /login instead of /prefix/login.

    I was able to fix the problems by

    • removing the request.uri_base from the templates
      <link rel="stylesheet" href="css/style.css">

    • by configuring the plugin to use the prefix
      plugins: Auth::Tiny: login_route: /prefix/login

    • by not using the / path, instead the main page is now /menu (because redirect('/') ignored the prefix, again, so I have to do redirect('menu') — i.e. no slash).

    Mentioning the prefix in the config definitely feels wrong. Hardcoding the prefix into the app? It also means the app can't be run locally on localhost for testing anymore.

    How should I properly write the app, configure it, and configure Apache to make it work both locally and in production, without hardcoding the prefix anywhere in the app?

    Interestingly, all Python flask and whatever apps written by other colleagues run as written without problems.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
XML::Twig not finding an element's parent's text
1 direct reply — Read more / Contribute
by mldvx4
on May 18, 2025 at 13:28

    Greetings, PerlMonks.

    I have run into a puzzle with XML::Twig where I am looking for specific elements and then need to find the text adjacent to those elements. The code snippet below illustrates the puzzle with one such sought after element and adjacent text in its __DATA__ section.

    #!/usr/bin/perl use XML::Twig; use strict; use warnings; my $xml = XML::Twig->new( twig_handlers => { 'text:bookmark' => \&handler_bookmark } ); $xml->parse(\*DATA); print qq(\n\n); $xml->print; exit(0); sub handler_bookmark { my ($twig, $bookmark)= @_; $bookmark->parent->print; } __DATA__ <?xml version="1.0" encoding="UTF-8"?> <text:h text:style-name="P900" text:outline-level="3"> <text:bookmark text:name="_asdfqwerzxcv"/>Foo bar </text:h>

    The two output items should be identical but are not. Specifically the string "Foo bar" is missing from the first output which has its origin in the handler_bookmark handler subroutine. I would expect that ->parent would still contain the text it started with, but it does not. Using ->parent->text does not retrieve the string either. Nor does using ->parent_text find it either.

    What can be done using XML::Twig to find the text "next to" an element?


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":


  • 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, details, 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, summary, 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.