Issue in Importing FIle using perl script

Perl questions on StackOverflow

Published by user2854259 on Tuesday 19 March 2024 07:55

I have a perl script to import Files as and when available, and if files are not available, it goes to sleep. The files are kept in a remote system. Layout of the code is as:

    while(1)
    {
    \\"Searching if Files Available for $date_yymmdd......"
    if (not -e $file)
    { \\ sleep }
    else 
    { 
    \\if file is not imported yet, then Import
    \\else sleep
    }
    }

So I intend this code be on infinite loop executing import duty as and when files are available.

So here is the thing. If I execute this code today, it does check if files are available and import as intended and then goes to sleep.

But then on next day, it does periodically check for files availability, but even if they are made available, the if condition (if (-e $file)) fails and script fails to realise that file is present.

Finally, if i terminate the script and re-run, then it again correctly identifies and imports file as intended without any change in script.

Why is it that i have to re run the script. Why does it fail in the if (-e $file) condition is what i dont get.

I am trying to run perl one liner to get the string from a header file "elf.h" which has following lines :-

#define ELFOSABIV_STDELF_V1          8U      // STD ELF ABI
#define ELFOSABIV_PRE_STDELF         7U      // latest abi version
#define ELFOSABIV_LATEST             6U      // latest abi version 

I am trying to get ELFOSABIV_LATEST version which is 6U. Actually i need to feed this output to executable file. So i have to go with perl one liner to make it simple.

Output :-

In Linux:-

perl -ne "print $1 if /#define\s+ELFOSABIV_LATEST\s+(\S+)/" /home/test/elf/elf.h
#define ELFOSABIV_LATEST             6U   // latest abi version 

In Windows:-

perl -ne "print $1 if /#define\s+ELFOSABIV_LATEST\s+(\S+)/" /home/test/elf/elf.h
 6U

Why is the difference in output among windows and linux above? Do i need to set something before printing. I need to make sure that output has to be 6U for both windows and linux.

I'm trying to practice pulling salary information from openpayroll.com. I need to be able to analyze the links on a given page and click on them if need be. When I run the following

mech-dump --all https://openpayrolls.com/other/utah-carbon-county-housing-authority

It only returns information regarding the headers but the links part is empty, i.e. it returns --> Links: and that's it. The page, however, is full of links. Do I need to pass an additional option to access all the links on the webpage?

Reversing Output (new to perl)

r/perl

Published by /u/wirikidor on Monday 18 March 2024 22:07

I have inherited some perl scripts that I've generally been able to edit well enough with my knowledge from other languages, but I need to make a change that has me stumped.

The user wants the output that happens from this loop to be reversed.

for ($nn=0;$nn<=$range_max;$nn++) { my $range=sprintf("%02d",$nn); $sum_of_A += $A_EACH_RANGE{"$range"}; $sum_of_B += $B_EACH_RANGE{"$range"}; printf("\"\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", $scale[$nn], commify($A_EACH_RANGE{"$range"}), commify($B_EACH_RANGE{"$range"}), commify($sum_of_A), commify($sum_of_B)); } 

So I figured all I had to do was start the for loop at the end like this:

for ($nn=$range_max;$nn>=0;$nn--) { 

Then I realized there's some cumulative math going on in the loop, which means the sum of everything needs to be at the top now instead of the bottom.

Now I'm stuck, I've made a few attempts like pushing it into an array so I could have the option to output in forward or reverse, but all my attempts just hang with no warnings or errors.

I figure there's a more elegant solution but my Google-fu hasn't helped.

submitted by /u/wirikidor
[link] [comments]

perldelta for ed37371b34c7f (Tie::File)

Perl commits on GitHub

Published by mauke on Monday 18 March 2024 18:43

perldelta for ed37371b34c7f (Tie::File)

My boss believes that perl program without explicit exit(0) at the end may return some other value, e. g. that one returned by the last function call in the program, or may be last system call. Perhaps he confuses it with bash. So he requires his programmers to put explicit exit(0) statement at the end of each perl script. Simple code examples or references to existing programs cannot convince him. Unfortunately I have no idea how to find the relevant topic in the documentation quickly: all keywords are too common. May be someone can point out exact place in the perl documentation what is the perl program exit code when the program just reaches its end, without any die or exit. (Yes, in fact I know what it is, but I need an official confirmation).

Note that I had set "equality" in double-quotes, so read on about the details:

I wrote some code that stores Perl objects in a file and retrieves them from there. I'm using my own JSON-based code using text representation to be independent from Perl. When I wrote a self-test checking whether the loaded object is the same as the stored object, I got a surprise:

  DB<14> x $self->time() == $other->time()
0  ''
  DB<15> x $self->time()
0  4842276.32536854
  DB<16> x  $other->time()
0  4842276.32536854
  DB<17> x $self->time() == $other->time()
0  ''
  DB<18> x $self->time() - $other->time()
0  '-2.79396772384644e-09'

So while the numbers output look identical, their internal representation is not. However when I create a JSON representation for both, there is no difference (different numbers this time (as time went on); also note that the order of the fields varies as it's a Perl HASH):

  DB<1> x $self->flat
0  '{"time":4842854.29538268,"crc":23407,"use_counter":19}'
  DB<2> x $other->flat
0  '{"use_counter":19,"crc":23407,"time":4842854.29538268}'

(The real objects are more complex, but this shows the principle; the time value comes from clock_gettime(CLOCK_MONOTONIC) # useTime::HiRes qw(clock_gettime CLOCK_MONOTONIC))

Now I wonder: Should I simply try to compare the numbers as strings (as a work-around), or should I use an elaborate ("correct") solution like https://stackoverflow.com/a/33024979/6607497?

FLOSS Weekly 765: Randal Schwartz

r/perl

Published by /u/briandfoy on Monday 18 March 2024 08:40

Randal Schwartz is guest on Flosss Weekly 765, mostly for Dart, but he also talks quite a bit about Perl.

One of the interesting management of Dart is that they have people assigned to work shifts to triage and respond to issues so that requestors can get immediate feedback that at least someone saw their issue. I'll let him tell the rest of the story, but it's a good one.

submitted by /u/briandfoy
[link] [comments]

Perl_tied_method(): *conditionally* use RC stack

Perl commits on GitHub

Published by iabyn on Monday 18 March 2024 07:54

Perl_tied_method(): *conditionally* use RC stack

Fixes GH #21784.

Perl_tied_method() is used to call tied methods for filehandles.  One of
its actions is to push a new stackinfo (and hence a new argument stack)
to run the method under. When the  method returns, any returned values
are copied back to to original stack and the stackinfo popped.  But
stackinfos (and the AV pointed to by si_stack) aren't freed at that
point; they are kept around until global destruction, in case they're
needed again.

Before this commit, Perl_tied_method() was incorrectly *always* making
the new stack AvREAL: this should in fact be done only on PERL_RC_STACK
builds.

The effect of this was that, on non-PERL_RC_STACK builds, any temp SVs
created as the return value(s) from the method call, would be left on
the abandoned stack, while the SVs themselves have long since been freed.
Normally this doesn't matter much - the array will be finally emptied
only during global destruction, which doesn't care if an already-freed
SV is attempted to be freed again.

But this was causing Coro to fail, because it maintains a stackinfo
chain per green thread, and manages and frees them itself, so they can
end up being freed before global destruction, triggering an 'Attempt to
free unreferenced scalar' warning.

For completeness, this commit now also resets PL_stack_sp to
PL_stack_base before abandoning the stack, so that that on PERL_RC_STACK
builds, there's no chance of the copied return value SVs being
double-counted later on,

Perl Weekly #660 - What's new ...

dev.to #perl

Published by Gabor Szabo on Monday 18 March 2024 05:43

Originally published at Perl Weekly 660

Hi there,

Happy Ramadan to all the readers who fast during this holy month. May ALLAH s.w.t accept your fasting, Ameen.

I recently became active on official Slack for The Perl Foundation after a long gap. I noticed it is very much active and live. Lots of positive noise and useful information shared with each other. I am not a big fan of Slack but after spending just few days, I find it easy to move around. I would like to keep an eye for important news and announcement. Earlier my only source of information was the good old https://blogs.perl.org. We used to have regular post by Perl enthusiasts but that has stopped unfortunately. And I don't blame them as I also stopped blogging completely. As and when I do blog, I use The Weekly Challenge platform. Having said, the platform is still used by some, for example Perl Steering Council for weekly updates. Every now and then, you do get some magical post by Perl fans. One such post, Changes in MooX::Role::Parameterized appeared last week by E. Choroba. I have been a big fan of Moo - Minimalist Object Orientation, so this post became even more important for me. Although, Corinna has made it to the Perl core, it is still a long way before it becomes a complete solution to all OO needs. I am looking forward to the next big release which would bring in some more features, hopefully.

What's new on CPAN?

I was introduced to perl.com by the post series What's new on CPAN? by David Farrell. It used to be regular every month with full of fun facts about new CPAN modules released. During those days, I used to be active on CPAN and released few CPAN. I had the honour to find place in the post often. Recently Olaf Alders took the initiative to revive the activities on perl.com. Because of his hard work and with the help of Mathew Korica we now have the post series back. You must check latest in the series, What's new on CPAN - February 2024.

I just realised that this is my 150th edition and in 2 months I will complete 6 years as co-editor of the Perl Weekly newsletter. It has been a very fruitful learning experience for me and I enjoyed it thoroughly.

Keep the spirit high and don't let the bad influence pull you down. Please do take care your health and loved ones.

--
Your editor: Mohammad Sajid Anwar.

Announcements

Registration for The Perl and Raku Conference 2024 is open!

Time has come to start preparing for the next big event. Please reserve your place as soon as you can.

Perl / Open Food Facts Hackathon in Paris

Teaming with the french mongers, Open Food Facts organize a Hackathon around the use of Perl by it's web server which is the heart of the project. It will take place in Paris, on Saturday March 23 and Sunday March 24. Remote participation is possible.

Articles

What's new on CPAN - February 2024

It is so pleasing to see my favourite series is back. Thank you the entire team behind this, you guys are doing a great service to keep this alive.

PSC #140 2024-03-14

Another week another update by the super charged Perl Steering Council.

CPAN

Changes in MooX::Role::Parameterized

For all Moo users, this is for you if you have worked with Roles. This change would make your life easy. Enjoy !!

Intellexer::API

Perl API client for Intellexer by Joshua Day, his first contribution to CPAN and hope not the last.

Grants

Maintaining Perl (Tony Cook) December 2023

Grant report for the work carried out by Tony Cook.

The Weekly Challenge

The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from all of the contributors during the month.

The Weekly Challenge - 261

Welcome to a new week with a couple of fun tasks: "Element Digit Sum" and "Multiply by Two". If you are new to the weekly challenge, why not join us and have fun every week? For more information, please read the FAQ.

RECAP - The Weekly Challenge - 260

Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Unique Occurrences" and "Dictionary Rank" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.

This Week a Ranking Occurred!

Adam's use of do { ... } for .. always fascinates me. Mind you this is happening alongside the latest Perl v5.38.

TWC260

Solution to dictionary rank blown me away. You must checkout his creative innovation.

Unique Rank

As always Raku is showing off with the help powerful feature of Bag. Keep it up great work.

Occurrences with BQN

Have you played with BQN? If not then you should as it is not just another programming language. Check out the post yourself.

13 x 20

Task analysis by Dace is unmatched. I just simply love the way he deals with challenge. Keep it up.

Perl Weekly Challenge: Week 260

Raku is presenting mathod chaining once again. It is one of my favourite. How about you?

Unique Multisets

Explore the mathematical view of the dictionay rank task. You may find it too complex but it is always fun.

Occurrencies and Permutations

Raku one-liner is showing the elegance. Raku Rocks !!

Perl Weekly Challenge 260

Using CPAN and still getting one-liner in Perl, incredible. Keep us entertained every week.

Unique Occurrences and Non-unique Permutations

We have seen how CPAN cam be handy is dealing with challenges. This week too, we saw the evidence.

Unique Dictionary Occurrences are Rank

I see Raku code written in Perl style. It tells Packy is a diehard Perl fan. Thank you for your contributions.

Uniquely ranked

Just a simple and straight forward approach, anyone can easily follow. Well done and keep it up.

The Weekly Challenge #260

For permuation related challenge, Math::Combinatorics is one of the choices CPAN provides. See the post how this solved the task.

Uniquely Rank

Unlike others Roger used Set of Raku language to deal with the challenge this week. In addition we got PostScript solution discussed too. Highly recommended.

Counting and ranking

Python is my new crush and everytime I read post about Python solution, it feels nice to be able to follow through. The use of defaultdic is one of them. Thanks for sharing.

Rakudo

2024.11 Membering

Weekly collections

NICEPERL's lists

Great CPAN modules released last week;
MetaCPAN weekly report;
StackOverflow Perl report.

You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.

Want to see more? See the archives of all the issues.

Not yet subscribed to the newsletter? Join us free of charge!

(C) Copyright Gabor Szabo
The articles are copyright the respective authors.

testsuite.yml: fix ASAN build tests

Perl commits on GitHub

Published by tonycoz on Monday 18 March 2024 02:31

testsuite.yml: fix ASAN build tests

This works around actions/runner-images#9491

Apparently a recent Ubuntu update changed the ASLR entropy to
use more bits which is incompatible with ASAN as shipped with
Ubuntu.

This adjusts the entropy bits to be compatible with ASAN.

Thanks to ilmari who found the ticket linked above.

Changes in MooX::Role::Parameterized

blogs.perl.org

Published by E. Choroba on Sunday 17 March 2024 20:10

What is it good for?

If you’ve never worked with MooX::Role::Parameterized or MooseX::Role::Parameterized, you might wonder what is a parameterized role at all?

Roles are used when you need to share behaviour among several classes that don’t have to be related by inheritance. Normally, a role just adds a bunch of methods to the class that consumes it (there’s more, you can for example specify which other methods the role expects to already exist).

A parameterized role makes it possible to provide parameters for the consumed role. This way, you can adjust the behaviour for each consuming class.

The old syntax

The standard syntax to apply a role to a class before version 0.100 of the module was to use the apply class method:

# My/Role.pm
package My::Role;
use Moo::Role;
use MooX::Role::Parameterized;

role {
    my ($params, $mop) = @_;
    $mop->has($params->{name} => is => $params->{is});
}
# My/Obj.pm
package My::Obj;
use Moo;
use My::Role;

'My::Role'->apply({
    name => 'size',
    is   => 'ro',
});

If we now created an object $o using my $o = 'My::Obj'->new(size => 2), we could get the value of the attribute size using the $o->size getter: the role created a new read-only attribute size for us.

The old experimental syntax

What I didn’t like about applying a role to a class the old standard way was it wasn’t declarative. You could easily overlook it as a block of code happening at runtime, while the meaning of the code was This is how a role is consumed. Therefore, I used the alternative experimental syntax:

package My::Obj;
use Moo;
use MooX::Role::Parameterized::With 'My::Role' => {
    name => 'size',
    is   => 'ro',
};

It's part of a use clause, so it’s clear that it’s happening at compile time.

The new syntax

I promoted one of my side-jobs to a full-time job recently. They gave me a new computer where I had to install all my code base to start working on it 8 hours a day instead of a couple a month.

Imagine my surprise when the code stopped with an error:

Can't locate object method "size" via package "My::Obj" at ./run.pl line 37.

Line 37 was where I called $o->size!

When installing the dependencies for my code, the most recent version of MooX::Role::Parameterized was installed from CPAN (0.501). The experimental syntax is no longer documented and as I found out, doesn’t work anymore.

The old non-experimental syntax still works, but there’s a new syntax, too. It uses the with keyword that looks like the one that can be used to consume a Moo::Role, but if we first use MooX::Role::Parameterized::With, it can also accept parameters for the role application.

package My::Obj;
use Moo;
use MooX::Role::Parameterized::With;

with 'My::Role' => {
    name => 'size',
    is   => 'ro',
};

Moreover, we should change the definition of the role, too. Parameters should be predeclared using the parameter keyword (similarly to MooseX::Role::Parameterized), and they can be then accessed via getters instead of peeking inside a parameter hash reference.

package My::Role;
use Moo::Role;
use MooX::Role::Parameterized;

parameter name => (is => 'ro');
parameter is   => (is => 'ro');

role {
    my ($params, $mop) = @_;
    $mop->has($params->name => is => $params->is);
}

We were wizards – a foreword to Learning Perl (1993)

r/perl

Published by /u/de_sonnaz on Sunday 17 March 2024 17:05

Getting rid of a warning

r/perl

Published by /u/ghiste on Sunday 17 March 2024 13:10

Hi,

I am using Template::Mustache in a prooted Debian in termux on Android.

It works fine, however it produces this annoying warning:

"Flock not available: 'Function not implemented': continuing in unsafe mode".

As far as I can see it ultimately comes from Path::Tiny when slurping a file.

I have tried to get rid of it with "no warnings" but that did not do the trick.

So how can I suppress this warning?

submitted by /u/ghiste
[link] [comments]

(cdlxxxvii) 12 great CPAN modules released last week

r/perl

Published by /u/niceperl on Sunday 17 March 2024 08:30

(cdlxxxvii) 12 great CPAN modules released last week

Niceperl

Published by Unknown on Sunday 17 March 2024 09:30

Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. App::DBBrowser - Browse SQLite/MySQL/PostgreSQL databases and their tables interactively.
    • Version: 2.407 on 2024-03-11, with 14 votes
    • Previous CPAN version: 2.405 was 28 days before
    • Author: KUERBIS
  2. App::Netdisco - An open source web-based network management tool.
    • Version: 2.073001 on 2024-03-13, with 16 votes
    • Previous CPAN version: 2.072003 was 28 days before
    • Author: OLIVER
  3. DBIx::DataModel - UML-based Object-Relational Mapping (ORM) framework
    • Version: 3.10 on 2024-03-11, with 12 votes
    • Previous CPAN version: 3.09 was 1 month, 15 days before
    • Author: DAMI
  4. HTML::Parser - HTML parser class
    • Version: 3.82 on 2024-03-13, with 47 votes
    • Previous CPAN version: 3.81 was 1 year, 1 month, 13 days before
    • Author: OALDERS
  5. LWP - The World-Wide Web library for Perl
    • Version: 6.77 on 2024-03-11, with 167 votes
    • Previous CPAN version: 6.76 was 1 month, 17 days before
    • Author: OALDERS
  6. LWP::Protocol::https - Provide https support for LWP::UserAgent
    • Version: 6.14 on 2024-03-11, with 20 votes
    • Previous CPAN version: 6.13 was 1 month, 5 days before
    • Author: OALDERS
  7. MetaCPAN::Client - A comprehensive, DWIM-featured client to the MetaCPAN API
    • Version: 2.031001 on 2024-03-11, with 24 votes
    • Previous CPAN version: 2.031000 was 4 months, 11 days before
    • Author: MICKEY
  8. Mozilla::CA - Mozilla's CA cert bundle in PEM format
    • Version: 20240313 on 2024-03-13, with 19 votes
    • Previous CPAN version: 20231213 was 3 months before
    • Author: LWP
  9. PAR::Packer - PAR Packager
    • Version: 1.063 on 2024-03-15, with 43 votes
    • Previous CPAN version: 1.062 was 10 days before
    • Author: RSCHUPP
  10. PPI - Parse, Analyze and Manipulate Perl (without perl)
    • Version: 1.278 on 2024-03-11, with 58 votes
    • Previous CPAN version: 1.277 was 5 months, 19 days before
    • Author: OALDERS
  11. Spreadsheet::ParseXLSX - parse XLSX files
    • Version: 0.34 on 2024-03-13, with 19 votes
    • Previous CPAN version: 0.33 was 5 days before
    • Author: NUDDLEGG
  12. SPVM - SPVM Language
    • Version: 0.989087 on 2024-03-15, with 31 votes
    • Previous CPAN version: 0.989085 was 6 days before
    • Author: KIMOTO

(dlxxxiii) metacpan weekly report - Spreadsheet::ParseExcel

Niceperl

Published by Unknown on Sunday 17 March 2024 09:27

This is the weekly favourites list of CPAN distributions. Votes count: 33

Week's winners (+3): Spreadsheet::ParseExcel 

Build date: 2024/03/17 08:26:48 GMT


Clicked for first time:


Increasing its reputation:

(dcvi) stackoverflow perl report

Niceperl

Published by Unknown on Sunday 17 March 2024 09:26

Counting and ranking

dev.to #perl

Published by Simon Green on Sunday 17 March 2024 07:19

Weekly Challenge 260

Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: Unique Occurrences

Task

You are given an array of integers, @ints.

Write a script to return 1 if the number of occurrences of each value in the given array is unique or 0 otherwise.

My solution

For this task I start by calculating the frequency of each integer, and store this in a dict (hash in Perl) called freq.

def uniq_occurrences(ints: list) -> bool:
    freq = defaultdict(int)
    for i in ints:
        freq[i] += 1

I then loop through the values of the dict (the frequency). If I have seen this frequency before, we know it is not unique, and can return False. If I haven't seen it, I add it to the seen dict in case we see it again.

Once I have looped through all values, I return True to indicate the occurrences are unique.

    seen = {}
    for i in freq.values():
        if i in seen:
            return False
        seen[i] = 1

The second part definitely fails under TMTOWTDI. One possible alternate solution is len(freq) == len(set(freq.values()). While probably quicker, it's not as straight forward to understand.

Examples

$ ./ch-1.py 1 2 2 1 1 3
1

$ ./ch-1.py 1 2 3
0

$ ./ch-1.py -2 0 1 -2 1 1 0 1 -2 9
1

Task 2: Dictionary Rank

Task

You are given a word, $word.

Write a script to compute the dictionary rank of the given word.

My solution

This task was a little more challenging than a first thought, and more so for the Perl solution. This is because while I can calculate all the permutations of letters easily, I only want to count unique permutations. For example, the word baa has 3! (6) permutations, but only 3 are unique (aab, aba, baa).

Thankfully there is a distinct_permutations method in more_itertools that makes this easy.

The first thing I do is convert the word into lower case and convert it into a tuple. I store this as the variable tuple_word.

I then sort the tuple alphabetically and store this as letters and parse it to the distinct_permutations generator. I keep counting until I find the tuple that has the original word.

def dictionary_rank(word: str) -> int:

    tuple_word = tuple(word.lower())
    letters = sorted(tuple_word)
    count = 0

    for perm in distinct_permutations(letters):
        count += 1
        if perm == tuple_word:
            break

    return count

It should be noted that the performance of the solutions are really only good if it appears early (alphabetically) or has less than 11 characters. Calculating the rank of 'kjihgfedcba' took 35 seconds on my PC. For the record it is ranked 39,916,800th which is also 11!.

Perl solution

The Perl solution is slightly different. My go to for permutations in Perl is usually Algorithm::Combinatorics, but this doesn't have a function for distinct permutations. Math::Combinatorics does, however the order of them is not guaranteed.

For the task, I count all unique permutations that are less than or equal to the word, and print that.

Examples

$ ./ch-2.py CAT
3

$ ./ch-2.py GOOGLE
88

$ ./ch-2.py SECRET
255

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

File Index

"ch-1.pl" Defined by 1.

"ch-2.pl" Defined by 5.

Part 1: Unique Occurrences

You are given an array of integers, @ints. Write a script to return 1 if the number of occurrences of each value in the given array is unique or 0 otherwise.

The complete solution is contained in one file that has a simple structure.

"ch-1.pl" 1


preamble 2
unique occurrences 3
main 4

For this problem we do not need to include very much. We’re specifying to use the current version of Perl, for all the latest features. We’re also using the boolean module, for the convenience of returning and displaying the return values.

This fragment is also used in Part 2.

preamble 2 ⟩≡


use v5.38;
use boolean;

Fragment referenced in 1, 5.

Here we have a single function which does essentially all the work. First we loop through the array of numbers and count occurrences. Then the counts are themselves used as hash keys to eliminate duplicates. If no duplicates are removed then the number of these new keys is equal to the number of original count values.

unique occurrences 3 ⟩≡


sub unique_occurrences{
my %occurrences;
do{
$occurrences{$_}++;
} for @_;
my %h;
do{$h{$_} = undef} for values %occurrences;
return boolean(values %occurrences == keys %h);
}

Fragment referenced in 1.

Finally, we have a few lines of code for running some tests.

main 4 ⟩≡


MAIN:{
say unique_occurrences 1, 2, 2, 1, 1, 3;
say unique_occurrences 1, 2, 3;
say unique_occurrences -2, 0, 1, -2, 1, 1, 0, 1, -2, 9;
}

Fragment referenced in 1.

Sample Run
$ perl perl/ch-1.pl 
1 
0 
1
    

Part 2: Dictionary Rank

You are given a word, $word. Write a script to compute the dictionary rank of the given word.

The solution to the second part of this week’s challenge is a little more complex than the first part. In the solution file we define our own function for computing all permutations of an array, which is then used to determine the dictionary rank.

"ch-2.pl" 5


preamble 2
Compute all valid permutations with Heap’s algorithm. 6
Determine the dictionary rank. 7
main 8

This function is a recursive implementation of Heap’s algorithm. A lot has been written on this algorithm, so I won’t go into much detail here.

Compute all valid permutations with Heap’s algorithm. 6 ⟩≡


sub permutations{
my($a, $k, $permutations) = @_;
if($k == 1){
push @{$permutations}, [@{$a}];
return true;
}
else{
permutations($a, $k - 1, $permutations);
for my $i (0 .. $k - 2){
if($k & 1){
($a->[0], $a->[$k - 1]) = ($a->[$k - 1], $a->[0]);
}
else{
($a->[$i], $a->[$k - 1]) = ($a->[$k - 1], $a->[$i]);
}
permutations($a, $k - 1, $permutations);
}
}
}

Fragment referenced in 5.

Now that we have a way to compute all permutations we will use that to determine the dictionary rank. There is a trick here. Keep in mind that dictionaries do not have multiple entries for repeated words! In the case of words with repeated letters than there will be permutations that are effectively equal in that they contain the same letters. Although they are created by permuting equal (but different) letters for ranking purposes we will consider them the same.

Determine the dictionary rank. 7 ⟩≡


sub dictionary_rank{
my($word) = @_;
my $permutations = [];
permutations [split //, $word], length($word), $permutations;
my %h;
do {$h{join q//, @{$_}} = undef} for @{$permutations};
my @permutations = sort {$a cmp $b} keys %h;
return (
grep {$permutations[$_] eq $word} 0 .. @permutations - 1
)[0] + 1;
}

Fragment referenced in 5.

main 8 ⟩≡


MAIN:{
say dictionary_rank q/CAT/;
say dictionary_rank q/GOOGLE/;
say dictionary_rank q/SECRET/;
}

Fragment referenced in 5.

Sample Run
$ perl ch-2.pl 
3 
88 
255
    

References

The Weekly Challenge 260
Generated Code
Heap’s Algorithm

PSC #140 2024-03-14

blogs.perl.org

Published by Perl Steering Council on Saturday 16 March 2024 20:58

This week, we discussed:

  • Further look down open bugs to tag some as being release-blocker
  • Do we want to revert PR21915? - discussed in its own email thread
  • Thought of a couple of issues to discuss with the wider group at the upcoming PTS
    • How to handle “important author is AWOL” for upstream CPAN issues
    • How to not break CPAN tests when adding new warnings to core

Registration for The Perl and Raku Conference 2024 is open!

Perl Foundation News

Published by Todd Rinaldo on Friday 15 March 2024 23:13


The Perl and Raku Conference (formerly knwn as YAPC::NA) is going strong! This year, we are celebrating 25 years, our silver anniversary, in the Silver State, Nevada! The main conference will be in Las Vegas on June 25-27, but there will be hackathons and possibly classes on the day before and the day after the conference (June 24th and 28th), so please consider joining us for the whole week!

The backbone of this conference has always been our tracks of "traditional" talks by community members and what we have come to call the "Hallway Track" the informal exchange of ideas and camaraderie that sparks new projects and fuels collaboration.

This year, we are pleased also to host the presentation of Papers and Posters accepted by the Science Perl Journal!

Registration is open, so your ticket can now be purchased.

Talk submissions are still open, and we are seeking proposals on a wide variety of subjects. This includes language features, personal projects, applications like Koha, and anything that may be of general interest to Perl and Raku programmers. (We had juggling and origami in the past. Fun!) * Talks can be 20 minutes or 50 minutes. Please submit through PaperCall. * Papers and Posters follow the guidelines of the Science Perl Journal. Links to both are also on https://tprc.us.

Speakers who are approved for a talk, paper, or poster will receive a free ticket to the event. The submission deadline is April 5th at 8pm EST, so please send us your submissions soon!

We are planning some special activities during the conference to celebrate our rich 25-year history.

Go now to https://tprc.us/ to check out what is planned and to book a room (see link to Alexis Park Resort under "Location"). Rooms start at only $75 per night, so it’s worth booking early!

The best way to register for the conference is at https://tprc2024.sched.com/tickets

Thanks, TPRC Admins

Faster tetranucleotide (k-mer) frequencies!

dev.to #perl

Published by Boyd Duffee on Friday 15 March 2024 08:31

I saw Jennifer's post about re-writing her perl scripts in python and how she saw a 2.5 times improvement.

How could this be? My favourite language can't be that slow.
It must be programmer error.

I have an interest in Perl and Science, so time to roll up sleeves and learn me some profiling/benchmarking. What follows is my internal monologue and the notes I scribbled down during the learning process. For those that want to follow along, I've created a small repo.

Getting started

Voltaire said that Hell is other people's code. My first step was to re-write it into Modern Perl and in the process, understand what each line does. When it's written idiomatically, it's easier to refactor and I should be able to make some minor performance improvements along the way.

Assume that the original script has been tested enough. For me to be correct, I've got to produce the exact same output. I got close, except for the header line.
line 99 print OUT "\t$prefix_$j"; becomes
line 89 print $out_fh "\t$j"; Yes, that's a bug because $prefix_ doesn't exist.

Search "benchmarking tools for linux" and decide that hyperfine is good for what I'm doing. Run Jennifer's new python script against my refactored perl and find that the python is 1.26 times faster for k=3 and 1.47 times faster for k=4. For the Covid-19 sequence, these are both on the order of hundreds of milliseconds.

hyperfine --warmup 3 'perl/get_kmer_frequencies.pl Covid-19_seq.fasta 3 boyd1' 'python/get_kmer_frequencies.py -i Covid-19_seq.fasta -k 3 -p boyd2'

Ok, not bad. Better than 2.9 times faster, but that's probably down to the way that hyperfine warms the cache and separates out User time from System time.

Oh, I should just check how much I improved when I refactored. Run it against Jennifer's original perl script and ... hers was 1.1 times faster. Well, that was a bit embarrassing.

ahem I was ... aiming at improving readability, .. maintainability, y'know best practice and all that. That's my story and I'm sticking to it. ;)

For sanity's sake

Check that the output of the new file is the same as the original, otherwise you've messed up the refactoring. I started using this test script with prove to make it quick and easy.
Saved as i.t, I run it with prove i.t for the lols.
It gets noisy when there's a problem, so I go back to running it by hand.

use Test2::V0;

my $standard = 'get_kmer_frequencies.pl';
my @files = sort { -M $a <=> -M $b } glob 'get_kmer*';
ok my $latest = shift @files;
isnt $latest, $standard, 'Files to compare';

my @args = qw'Covid-19.fasta 3';
ok system('perl', $standard, @args, 'A') == 0, 'Make A_kmers.txt';
ok system('perl', $latest, @args, 'B') == 0, 'Make B_kmers.txt';

is `diff A_kmers.txt B_kmers.txt`, q{}, 'No differences in output';

done_testing();

Clever people do this from the start.
I did this after a bug I introduced messed up the output and I hadn't immediately noticed. What it was is that I changed the key separator to a character that was found in some of those keys and it then split those keys. Oops.

NYTProf time

When you get serious about optimizing programs, trying to enhance performance, you reach for profiling tools that can analyze your code's memory or time complexity. In Perl, Devel::NYTProf comes highly recommended. I use it to collect data on the number of times each statement is called and how long it spends executing it. That way I can work out where to invest the effort making the script faster, what gives the most bang for the buck.

Grab the profiler and run

perl -d:NYTProf get_kmer_frequencies.pl Covid-19_seq.fasta 3 boyd1

and open up the nytprof/index.html using nytprofhtml --open to see

Calls   P   F   Exclusive Time  Inclusive Time  Subroutine
9653    1   1   31.6ms  31.6ms  main::rc_seq
25      2   1   28.1ms  59.7ms  main::process_it
82498   7   1   9.46ms  9.46ms  main::CORE:print (opcode)
3175    4   1   7.89ms  7.89ms  main::CORE:sort (opcode)

Sorting out the sort

Obviously, the rc_seq is the big sub that needs attention, but what about that sort? Quickly looking at the sort on Line 78 for my $i (keys %knucs) I see that there's no reason to sort those keys. Saved one sort and the script runs about the same. There's another sort inside a loop which can be extracted out of the loop. Extracting that made it run 1.15 times faster!

Changing the header line (line 87) from a for loop to a join over a list is 1 or 2 percent faster.

How do I print thee? Let me count the ways.

Messing about with printing in the inner loop didn't gain much, but changing the key separator from a tab "\t" (interpolated string) to an underscore '_' (a string literal) made a 10% improvement. (it also introduced the bug noted above because the keys used the underscore. changed it to a colon - bug gone)

say is marginally slower than print so use print inside the loop that gets called a lot to save maybe 10% on that call. From 32ms to 28ms is a small, but nice gain for a one line change.

rc_seq - transforming the sequence

The rc_seq sub is an if-elsif block that splits a string into individual characters, translates ACGT into their complement (TGCA), reverses the array and joins it back into a string.

Being Perl, we can manipulate and reverse the string in-place. The change makes it shorter and more obvious (sometimes it runs faster). Actually, I ran this through the profiler and the sub now runs 5 times faster.

process_it - collecting the frequencies

This sub does the work of splitting the sequence into kmers and counting them. The longest time spent here is incrementing the %knucs hash.

The second longest time is spent turning the sequence into an array of letters to create all the kmer substrings. Splitting isn't bad, but joining sets of letters together is. Use the string function, substr instead and speed that line up by 5 times.

Now marginally faster the python script in speed. Over 20% faster for k=3, and 5% (+/- 5%) faster for k=4. That's a decent improvement.

Like the end of a great song ... a Key change!

line 91

my @items = map { my $key = join ':', $_, $i; $knucs{$key} // 0 } @record_keys;

The script spends most of its time (55ms!!!), longer than anything else, on this line.

Assume that the problem isn't the map but constructing the key for the lookup. Change the key to a 2 dimensional lookup and see if that improves things.

WHEN you finally get it right (and remember the correct order that you construct the keys in), line 92 is now 2.5 times faster than before and the perl script is now 40% faster than the python script.

Keys are constructed/used on lines 79, 91, 135

STOP!!!!

Know when to stop.

There are no more obvious or easy gains here. Any more work is likely to yield small returns. Go outside, have a life or at the least consult the relevant chart.

Well, after thinking a while, maybe constructing the output could be improved, but I'm moving on. I've exceeded my goal of making the perl script as fast as the python script and learned more about refactoring and profiling. A bit like how audiophiles use your music to listen to their equipment, I've used Jennifer's science to better understand my Perl and had fun doing it.

There's a niggling thought at the back of my mind, now that I feel I better understand the purpose of the script, whether BioPerl can do this even faster. I will leave that for another day. Oh, look glycine has already done most of the hard work for me. Many thanks!

Lessons learned

In summary, these are reflections on the changes that I made in chronological order. This may be someone's first time considering performance, so I include basic rules of thumb I used along with the things I did not know before.

  • Modern Perl style adds a small amount of overhead, but the sanity it brings is a price worth paying.
  • Streamline a method of checking the output hasn't changed
  • Don't sort when order is not important
  • Calculate constant values outside of loops
  • Use built-in list functions over loops (join instead of for)
  • Interpolated strings are slower than string literals (prefer single quotes over double quotes)
  • say is slightly slower than print. Avoid it in heavy loops.
  • substr is faster than spliting and joining
  • Creating a single hash key is slower than using a 2 level hash

The Human Genome is way too large. Grab the protein sequence for Caenorhabditis elegans. It takes about 5 minutes to run.

Run your frequent tests with the Covid-19 sequence. Repeated runs with anything larger take too long for rapid turnaround.

WARNING: hyperfine will run each program 20 to 40 times to get decent statistics. You won't want to wait around for a file that takes 5 minutes to process a single run.

I'll leave you with a couple of related references for further reading, chrisarg's work on parsing FastQ files fast
and a marketsplash tutorial on Perl code profiling tools

In Conclusion

My corollary to Cunningham's Law:
Don't ask people how to make your code run faster;
Tell them their language is slow

It's taken a lot longer to reply Jennifer's post than I'd anticipated, but right now I have the warm glow that comes from being able to say, (until someone iterates on the above corollary)

... Python is SLOW!

What's new on CPAN - February 2024

perl.com

Published on Thursday 14 March 2024 21:19

Welcome to “What’s new on CPAN”, a curated look at last month’s new CPAN uploads for your reading and programming pleasure. Enjoy!

APIs & Apps

Config & Devops

Data

Development & Version Control

Language & International

Web

Other

autodoc.pl: fix typos

Perl commits on GitHub

Published by testwill on Thursday 14 March 2024 19:09

autodoc.pl: fix typos

AUTHORs update

Note that __VA_OPT__ is now standardized

Perl commits on GitHub

Published by khwilliamson on Thursday 14 March 2024 03:13

Note that __VA_OPT__ is now standardized

whereas before we said it had never been standardized

Google started offering a Perl API for advertising from 2020.

dev.to #perl

Published by Yuki Kimoto - SPVM Author on Wednesday 13 March 2024 02:18

Google recently started offering a Perl API for advertising from 2020.

Perl Client Libraries - Google Ads API

Perl, a high-level, interpreted programming language, has been a stalwart in the world of computer science since its inception in the late…

Maintaining Perl (Tony Cook) December 2023

Perl Foundation News

Published by alh on Monday 11 March 2024 08:10


Tony writes:

``` [Hours] [Activity] 2023/12/04 Monday 0.42 #21677 minor fix. testing 0.23 #21661 check smoke results, minor commit message edit, make PR 21683 1.90 #21680 testing, debugging 1.28 #21680 fixes, testing, push for CI 1.42 #21651 testing and reproduce, try a fix and testing, push

for CI

5.25

2023/12/05 Tuesday 0.30 #21677 research 0.95 #21664 apply to blead, perldelta, comment on original perlmonks post 0.82 #13814 research 0.38 #13814 try a different approach

0.62 #13814 get it working, add tests, testing, push for CI

3.07

2023/12/06 Wednesday 1.07 #13814 review CI results, documentation, testing, make PR 21693 2.48 #21692 review, comments, try to work out getlines() cleanup 1.52 #21692 finally figure it out, comment 0.13 #21686 testing and comment 0.57 #16535 research and close 0.12 #16529 research and close

0.08 #16522 testing

5.97

2023/12/07 Thursday 0.38 #17457 rebase, retest, push for CI 2.03 #17435 testing, work on a fix, more testing 0.35 #21679 apply to blead, perldelta 0.75 #13814 changes per comments

0.10 #17457 check CI results, make PR 21696

3.61

2023/12/08 Friday 0.35 #21696 apply to blead, update dist/IO/Changes

0.25 #13814 apply to blead, perldelta

0.60

2023/12/11 Monday 0.20 #21684 follow-up 0.72 #21701 research and comment 0.63 #21705 research and comment 0.60 #21702 testing, research and approve 0.08 #21706 review and approve 0.13 #21703 review and approve 0.08 #21699 review and approve 0.08 #21698 review and approve 0.08 #21704 review and approve 0.17 #21700 review and approve 1.03 #21701 testing, research, comment 0.13 #21708 review and approve

0.15 #21709 review and approve

4.08

2023/12/12 Tuesday 1.02 #21712 review the code, testing, comment (not a bug) 0.68 #21684 apply to blead, look at regenning the deps

0.23 #21684 more deps

1.93

2023/12/13 Wednesday 0.27 #21705 research and comment 0.22 #21710 review and approve 2.38 #21714 review and approve, comment 0.27 #21711 review and approve 0.18 #21713 review and approve 0.40 #21676 review and approve

2.42 #21684 more deps

6.14

2023/12/14 Thursday 0.12 #21714 follow-up 1.83 #21701 testing and research, comment

0.63 #21684 more deps

2.58

2023/12/18 Monday 0.42 #21725 debugging, comment 1.38 #21716 debugging. research, comment, work on a fix, push

for CI

1.80

2023/12/19 Tuesday 1.08 #21716 minor fixes, testing and comments 0.62 #21725 add comment 0.85 #21719 review, research and comments

0.32 #21720 try to understand the diff

2.87

2023/12/20 Wednesday 0.45 #21723 review, research and approve 0.18 #21726 review, research (alternate openbsd libc anywhere?, apparently not), approve 0.23 #21728 review and approve 0.58 #21720 review, comments and approve 0.25 #21731 follow-up comment 0.70 #21636 re-work 1.03 #21636 more re-work, testing and push 0.50 #21732 testing and comment, work on fixing the most

obvious build related issues and push for CI

3.92

2023/12/21 Thursday 0.08 #21732 review discussion, check CI results and create PR 21737 0.20 #21716 review discussion and comment 0.15 #21719 review updates and approve

1.05 #21718 debugging

1.48

Which I calculate is 43.3 hours.

Approximately 44 tickets were reviewed or worked on, and 5 patches were applied. ```

Perl Weekly #659 - The big chess game

dev.to #perl

Published by Gabor Szabo on Monday 11 March 2024 07:47

Originally published at Perl Weekly 659

My father was a chess player. In his best time he was sometimes called "the best non-Russian chess player". He survived WWII and the Holocaust in a Hungarian forced labor camp and in Russian POV camp. When he got back to Hungary all he wanted to do is get back to chess. He did not want to care about 'politics'.

In the 90s he often lamented that he did not pay enough attention to what went on in Hungary in the 50's. That he was not aware of the communist atrocities in Hungary and neighboring countries.

I have been publishing the Perl Weekly for more than 12 years. In the first 9-10 year I think I have never mentioned anything besides Perl or related technologies. I wish I could keep focusing on technology only. Unfortunately I don't have that luxury any more.

Frankly, if we paid more attention to what's going on outside of Perl and outside of technology in general, maybe we would not be in such a bad situation.

On a related subject, I hear Garry Kasparov was added to the list of 'terrorists and extremists' by Russia.

We can't change the past - well, some do it anyway by lying about history - but we also cannot claim we did not know. We want to bring them home!

Have a better week!

--
Your editor: Gabor Szabo.

Articles

Reading sequences from FASTA format alignment by Bio::Perl

Pointless personal side projects

I think only a very little subset of programmers have such side projects and an even smaller subset write articles about these projects. For most people programming is a 9-5 job. It is not that others aren't as good or don't enjoy programming. It is just that they might have different hobbies, or no time for hobbies at all. Comment on Reddit or on DEV.to.

Some guidance how to set this up

A very non-descriptive title for some logging/debugging advice.

Discussion

A little confused about cpan

How to remove packages?

Is there a better way to write this alienfile?

Grants

PEVANS Core Perl 5: Grant Report for February 2024

Maintaining Perl 5 Core (Dave Mitchell): January - February 2024

Perl

This Week in PSC (139)

The Weekly Challenge

The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from among all of the contributors during the month.

The Weekly Challenge - 260

Welcome to a new week with a couple of fun tasks "Unique Occurrences" and "Dictionary Rank". If you are new to the weekly challenge then why not join us and have fun every week. For more information, please read the FAQ.

RECAP - The Weekly Challenge - 259

Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Banking Day Offset" and "Line Parser" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.

Banking Left Into the Parser Zone

Do you know yapp? Want to quick introduction? You have to checkout this post.

Day Parser

Raku making good use of built-in support for Date. Raku rocks !!!

What We Did On Our Bank Holiday

You will fall in love with Perl again when you see it's regex power. Keep it up great work.

Holiday Parser

Don't you love CPAN? Well it is the USP of Perl. Checkout how CPAN helped solve the task.

too much work to do!

Using regex type of Raku make code looks clean and elegant. Well done.

Perl Weekly Challenge 259

Do you want to learn regex grammar then checkout this post. Cool work.

I Have a Date With a Parser

Magical Perl regex in action. No one can beat Perl in regex. Cool work.

Ba-a-nking Day! Ba-a-nking Day! That’s all I really wanted to say…

Date::Names of Raku is used to solve this week task. Thanks for sharing knowledge with us.

Dates and parsing

A thorough solution to the Date task is not to be missed. Highly recommended.

Banking Parser

This week Raku is the lucky language to be discussed with the power Date object. You also get seamless discussion as well.

Bank Holidays and Line Parser

This is what I was missing for so long. What a quality post we have. Thanks for your contribution.

Weekly collections

NICEPERL's lists

Great CPAN modules released last week;

You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.

Want to see more? See the archives of all the issues.

Not yet subscribed to the newsletter? Join us free of charge!

(C) Copyright Gabor Szabo
The articles are copyright the respective authors.

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1: Banking Day Offset

You are given a start date and offset counter. Optionally you also get bank holiday date list. Given a number (of days) and a start date, return the number (of days) adjusted to take into account non-banking days. In other words: convert a banking day offset to a calendar day offset.

Non-banking days are:

(a)
Weekends
(b)
Bank holidays

Using Time::Piece the work can be contained in a single function. Really the main piece of logic required of sub count_days() is for us to check if a day is a weekend or bank holiday.

count days 1 ⟩≡


sub count_days{
my($start, $offset, $holidays) = @_;
$start = Time::Piece->strptime($start, q/%Y-%m-%d/);
my $t = $start;
my $end = $start;
{
$t += ONE_DAY;
unless(The day is a weekend. 2 || The day is a bank holiday. 3 ){
$end = $t;
$offset--;
}
redo if $offset > 0;
}
return $end->strftime(q/%Y-%m-%d/);
}

Fragment referenced in 4.

The day is a weekend. 2 ⟩≡


$t->wday >= 6

Fragment referenced in 1.

The day is a bank holiday. 3 ⟩≡


1 == grep {$t->strftime(q/%Y-%m-%d/) eq $_} @{$holidays}

Fragment referenced in 1.

The rest of the code just tests this function.

"perl/ch-1.pl" 4


preamble 5
count days 1
main 6

preamble 5 ⟩≡


use v5.38;
use Time::Piece;
use Time::Seconds;

Fragment referenced in 4.

main 6 ⟩≡


MAIN:{
say count_days q/2018-06-28/, 3, [q/2018-07-03/];
say count_days q/2018-06-28/, 3;
}

Fragment referenced in 4.

Sample Run
$ perl perl/ch-1.pl 
2018-07-04 
2018-07-03
    

Part 2: Line Parser

You are given a line like below:

{% id field1=“value1”field2=“value2”field3=42 %}

Where

(a)
“id”can be \w+.
(b)
There can be 0 or more field-value pairs.
(c)
The name of the fields are \w+.
(d)
The values are either number in which case we don’t need double quotes or string in which case we need double quotes around them.

The line parser should return a structure like:

{ 
       name => id, 
       fields => { 
           field1 => value1, 
           field2 => value2, 
           field3 => value3, 
       } 
}
    

It should be able to parse the following edge cases too:

{%  youtube title="Title\"quoted\"done" %}
    

and

{%  youtube title="Titlewithescapedbackslash\\" %}
    

Most of the work is done in a parser constructed using Parse::Yapp.

ch-2.pl

First off, before we get into the parser, here is a small bit of code for driving the tests.

print the parser results 7 ⟩≡


sub print_record{
my($record) = @_;
say q/{/;
say qq/\tname => / . $record->{name};
say qq/\tfields => {/;
for my $field (sort {$a cmp $b} keys %{$record->{fields}}){
say qq/\t\t$field => / . q/ / . $record->{fields}->{$field};
}
say qq/\t}/;
say q/}/;
}

Fragment referenced in 8.

The rest of the code drives some tests.

"perl/ch-2.pl" 8


preamble 9
print the parser results 7
main 10

preamble 9 ⟩≡


use v5.38;

use Ch2;
use constant TEST0 => q/{% id field1="value1" field2="value2" field3=42 %}/;
use constant TEST1 => q/{% youtube title="Title␣\"quoted\"␣done" %}/;
use constant TEST2 => q/{% youtube title="Title␣with␣escaped␣backslash␣\\\\" %}/;

Fragment referenced in 8.

main 10 ⟩≡


MAIN:{
my $parser = Ch2->new();
say TEST0;
print_record($parser->parse(TEST0));
say TEST1;
print_record($parser->parse(TEST1));
say TEST2;
print_record($parser->parse(TEST2));
}

Fragment referenced in 8.

The Parser

Here is where the work is really done. Parse::Yapp is given the following grammar. A parser is generated, contained in it’s own module.

First off is the grammar’s header. Here we define the symbols used in the rules which follow. We also add a small code block which contains a hash for holding the structure obtained from the parsed text.

header 11 ⟩≡


%token NUMBER
%token START
%token END
%token WORD
%token QUOTE
%token ESCAPED_QUOTE
%{
my %record = (fields => {});
%}

Fragment referenced in 17.

Here is the most important section, the rules for processing the input! For some rules we have also added action code blocks. We want to construct a data structure from the given input and in these action code blocks that final result is accumulated. Remember, the first rule is going to be called last, when the input is complete, so there we give a reference to a hash containing the result. This is the return value for the parse function found in the grammar’s footer.

rules 12 ⟩≡


file: START id fields END {$record{name} = $_[2]; \%record;}
;

id: WORD
;

words: WORD
| words WORD
| words ESCAPED_QUOTE WORD ESCAPED_QUOTE
;

field: WORD ’=’ NUMBER {$record{fields}->{$_[1]} = $_[3]}
| WORD ’=’ QUOTE words QUOTE {$record{fields}->{$_[1]} = $_[4]}
;

fields: field
| fields field
;

Fragment referenced in 17.

The footer contains additional Perl code for the lexer, error handing, and a parse function which provides the main point of execution from code that wants to call the parser that has been generated from the grammar.

The lexer function is called repeatedly for the entire input. Regular expressions are used to identify symbols (the ones declared in the header) and pass them along for the rules processing.

lexer 13 ⟩≡


sub lexer{
my($parser) = @_;
$parser->YYData->{INPUT} or return(’’, undef);
$parser->YYData->{INPUT} =~ s/^[ \t]//g;
##
# send tokens to parser
##
for($parser->YYData->{INPUT}){
s/^([0-9]+)// and return ("NUMBER", $1);
s/^({%)// and return ("START", $1);
s/^(%})// and return ("END", $1);
s/^(\w+)// and return ("WORD", $1);
s/^(=)// and return ("=", $1);
s/^(")//␣and␣return␣("QUOTE",␣$1);
s/^(\\")//␣and␣return␣("ESCAPED_QUOTE",␣$1);
s/^(\\\\)// and return ("WORD", $1);
}
}

Fragment referenced in 16.

The parse function is for the convenience of calling the generated parser from other code. yapp will generate a module and this will be the module’s method used by other code to execute the parser against a given input.

Notice here that we are squashing white space, both tabs and spaces, using tr. This reduces all repeated tabs and spaces to a single one. The eases further processing since extra whitespace is just ignored, according to the rules we’ve been given.

Also notice the return value from parsing. In the rules section we provide a return value, a hash reference, in the final action code block executed.

parse function 14 ⟩≡


sub parse{
my($self, $input) = @_;
$input =~ tr/\t/ /s;
$input =~ tr/ //s;
$self->YYData->{INPUT} = $input;
my $result = $self->YYParse(yylex => \\&lexer, yyerror => \\&error);
return $result;
}

Fragment referenced in 16.

This is really just about the most minimal error handling function there can be! All this does is print “syntax error”when the parser encounters a problem.

error handler 15 ⟩≡


sub error{
exists $_[0]->YYData->{ERRMSG}
and do{
print $_[0]->YYData->{ERRMSG};
return;
};
print "syntax␣error\n";
}

Fragment referenced in 16.

footer 16 ⟩≡


lexer 13
error handler 15
parse function 14

Fragment referenced in 17.

"perl/ch-2.yp" 17


header 11
%%
rules 12
%%
footer 16

Sample Run
$ yapp -m Ch2 perl/ch-2.yp; mv Ch2.pm perl; perl -I. ch-2.pl 
{%  id    field1="value1"    field2="value2"    field3=42 %} 
{ 
        name => id 
        fields => { 
                field1 =>  value1 
                field2 =>  value2 
                field3 =>  42 
        } 
} 
{%  youtube title="Title\"quoted\"done" %} 
{ 
        name => youtube 
        fields => { 
                field1 =>  value1 
                field2 =>  value2 
                field3 =>  42 
                title =>  Title 
        } 
} 
{%  youtube title="Titlewithescapedbackslash\\" %} 
{ 
        name => youtube 
        fields => { 
                field1 =>  value1 
                field2 =>  value2 
                field3 =>  42 
                title =>  Title 
        } 
}
    

File Index

"perl/ch-1.pl" Defined by 4.

"perl/ch-2.pl" Defined by 8.

"perl/ch-2.yp" Defined by 17.

References

The Weekly Challenge 259
Generated Code

Reading sequences from FASTA format alignment by Bio::Perl

blogs.perl.org

Published by glycine on Saturday 09 March 2024 22:11

Show code for TL;DR:

use Bio::AlignIO;

my $in = Bio::AlignIO->new(

       -file   => $inputfilename ,

       -format => 'fasta',

     );

while ( my $aln = $in->next_aln() ) { 

    foreach my $seq ($aln->each_seq) {

        ...; # do some thing 

    }

}

Bio::Perl is a famous library for managing bioinformatics data, although all knowledge mentioned here can fetch from documents on cpan or Bio::Perl webpages, but I believe there can be numerous articles to explain the same thing. :)

Basic concept

The most difficult aspect for me is understanding which classes' documentation should I read, which object will be generated? and then, which method on which object do I need to invoke for the data I wanted?

so let me descript how a Bio::AlignIO object formed.

Weesperplein.svg

  1. Bio::AlignIO object can contain multiple alignments.

  2. Bio::SimpleAlign contains one alignment.

  3. Bio::LocatableSeq contains one aligned sequence.

For example, let's presume I have a file containing COI alignment for ten samples. If I use this file to call Bio::AlignIO->new(), the new Bio::AlignIO object will contain only one Bio::SimpleAlign object which contains this COI alignment. Then, the Bio::SimpleAlign object contains ten Bio::LocatableSeq objects for aligned COI sequences of each sample.

one alignment is tranditional one gene or multiple genes alignment, e.g., a COI alignment in here. Usually this type of alignment data is stored one file like phylip, nexus or fasta. but Bio::AlignIO can manage blast output, too. so Authors keep the ability of contain multiple alignments in one Bio::AlignIO object. In my condition, I just directly get first Bio::SimpleAlign from it.

Extract sequences

Today I just wanted to retrieve the sequences of each sample in my alignment file (fasta) and import them into Perl. To achieve this, first, we need to call the new method to create a new Bio::AlignIO object, using the alignment file as an argument:

my $in = Bio::AlignIO->new(
       -file   => $inputfilename,
       -format => 'fasta',
     );

Then, we want to extract Bio::SimpleAlign objects from the Bio::AlignIO object. For convenience, we use the same method as described in the Bio::AlignIO documentation. We use a while loop to iterate through each Bio::SimpleAlign object contained in the Bio::AlignIO object (although we know there is only one):

while ( my $aln = $in->next_aln() ) { ... ;}

Now, we need to extract Bio::LocatableSeq objects from Bio::SimpleAlign. Calling the each_seq() method of Bio::SimpleAlign allows us to retrieve Bio::LocatableSeq objects, each storing a sequence:

foreach my $seq ($aln->each_seq) { ...; }

At this point, we're nearly done. Simply by calling the seq() and id() methods of Bio::LocatableSeq objects, we can obtain the sequence ID and the actual sequence data. For instance, to print out the base pairs of each sequence:

foreach my $seq ($aln->each_seq) {print $seq->seq(), "\n"}

References:

  1. Bio::AlignIO
  2. Bio::SimpleAlign
  3. Bio::LocatableSeq
  4. https://en.wikipedia.org/wiki/Sequence_alignment

(cdlxxxvi) 15 great CPAN modules released last week

Niceperl

Published by Unknown on Saturday 09 March 2024 22:04

Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. CGI - Handle Common Gateway Interface requests and responses
    • Version: 4.63 on 2024-03-06, with 43 votes
    • Previous CPAN version: 4.62 was 5 days before
    • Author: LEEJO
  2. CPAN::Audit - Audit CPAN distributions for known vulnerabilities
    • Version: 20240307.001 on 2024-03-09, with 13 votes
    • Previous CPAN version: 20240302.001 was 6 days before
    • Author: BDFOY
  3. Devel::MAT - Perl Memory Analysis Tool
    • Version: 0.53 on 2024-03-07, with 29 votes
    • Previous CPAN version: 0.52 was 1 month, 25 days before
    • Author: PEVANS
  4. Expect - automate interactions with command line programs that expose a text terminal interface.
    • Version: 1.38 on 2024-03-08, with 28 votes
    • Previous CPAN version: 1.36 was 14 days before
    • Author: JACOBY
  5. Firefox::Marionette - Automate the Firefox browser with the Marionette protocol
    • Version: 1.53 on 2024-03-03, with 15 votes
    • Previous CPAN version: 1.53 was before
    • Author: DDICK
  6. Mojolicious - Real-time web framework
    • Version: 9.36 on 2024-03-08, with 493 votes
    • Previous CPAN version: 9.35 was 4 months, 12 days before
    • Author: SRI
  7. Number::Phone - base class for Number::Phone::* modules
    • Version: 4.0002 on 2024-03-08, with 17 votes
    • Previous CPAN version: 4.0001 was 2 months, 29 days before
    • Author: DCANTRELL
  8. PAR - Perl Archive Toolkit
    • Version: 1.020 on 2024-03-04, with 19 votes
    • Previous CPAN version: 1.019 was 4 months, 3 days before
    • Author: RSCHUPP
  9. PAR::Packer - PAR Packager
    • Version: 1.062 on 2024-03-05, with 43 votes
    • Previous CPAN version: 1.061 was 2 months, 21 days before
    • Author: RSCHUPP
  10. PerlPowerTools - BSD utilities written in pure Perl
    • Version: 1.044 on 2024-03-03, with 39 votes
    • Previous CPAN version: 1.044 was before
    • Author: BRIANDFOY
  11. Redis::Fast - Perl binding for Redis database
    • Version: 0.37 on 2024-03-08, with 13 votes
    • Previous CPAN version: 0.36 was 8 months, 3 days before
    • Author: SHOGO
  12. Spreadsheet::ParseXLSX - parse XLSX files
    • Version: 0.33 on 2024-03-08, with 19 votes
    • Previous CPAN version: 0.31 was 1 month, 21 days before
    • Author: NUDDLEGG
  13. Spreadsheet::XLSX - Perl extension for reading MS Excel 2007 files.
    • Version: 0.18 on 2024-03-09, with 19 votes
    • Previous CPAN version: 0.17 was 2 years, 4 months, 6 days before
    • Author: ASB
  14. SPVM - SPVM Language
    • Version: 0.989085 on 2024-03-09, with 31 votes
    • Previous CPAN version: 0.989082 was 8 days before
    • Author: KIMOTO
  15. SQL::Abstract::More - extension of SQL::Abstract with more constructs and more flexible API
    • Version: 1.43 on 2024-03-05, with 22 votes
    • Previous CPAN version: 1.42 was 1 month, 14 days before
    • Author: DAMI

Pointless personal side projects

Perl Hacks

Published by Dave Cross on Saturday 09 March 2024 16:10

I can’t be the only programmer who does this. You’re looking for an online service to fill some need in your life. You look at three or four competing products and they all get close but none of them do everything you want. Or maybe they do tick all the boxes but they cost that little bit more than you’re comfortable paying. After spending a few hours on your search that little voice pops up in your head with that phrase that you really don’t want to hear:

Maybe you should just write your own version. How hard can it be?

A couple of hours later, you have something that vaguely works, you’ve learned more than you thought there was to learn about some obscure corner of life and you’re the proud owner of another new domain.

Please tell me it’s not just me.

So today I’ve been working on my Linktree clone.

Honestly, I can’t remember what it was about Linktree or its existing clones that I didn’t like. I suspect it’s that I just wanted more control over my links page than a hosted service would give me. All I can be sure of is that in September 2022 I made the first commit to a project that, eighteen months later, I’m still maintaining and improving.

To be fair to myself, I didn’t buy a new domain. That means I’m getting better, right? The output is hosted at links.davecross.co.uk. I’m not even paying for hosting as it’s all hosted on GitHub Pages – it’s a static site that has occasional changes, so it’s perfect for GitHub Pages.

But I have spent quite a lot of time working on the code. Probably more than is reasonable for a web site that gets a dozen visits in a good month. Work on it seems to come in waves. I’ll go for months without touching it, and then I’ll spend a week or so working on it pretty much every day. Over the last 24 hours or so, I’ve passed an important milestone. Like all of these little side projects, this one started out as a largely unstructured code dump – as I worked to get it doing something that approximated the original goal. Then I’ll spend some time (months, usually) where fixes and improvements are implemented by hacking on the original horrible code. At some point. I’ll realise that I’m making things too difficult for myself and I’ll rewrite it (largely from scratch) to be better structured and easier to maintain. That’s where I got to today. The original single-file code dump has been rewritten into something that’s far nicer to work on. And as a side benefit, I’ve rewritten it all using Perl’s new, built-in object orientation features – which I’m loving.

Oh, and I guess that’s the upside of having little side projects like this – I get to try out new features like the new OO stuff in a no-pressure environment. And just spending time doing more programming has to make you a better programmer, right? And surely it’s just a matter of time before one of these projects takes off and turns me into a millionaire! I’m not saying for a minute that having pointless side projects is a bad idea. I’m just wondering how many pointless side projects are too many 🙂

So, that’s my guilty secret – I’m a serial writer of code that doesn’t really need to be written. What about you? How many pointless side projects do you have? And how much of your spare time do they use up?

The post Pointless personal side projects appeared first on Perl Hacks.

This Week in PSC (139)

blogs.perl.org

Published by Perl Steering Council on Thursday 07 March 2024 22:28

Just Paul and Philippe this week:

  • Paul volunteers to do the 5.39.9 release. We still need people for .10 and 5.40. The .10 release will be timed around PTS - so maybe we could do something “live” at the summit?
  • Mailing list was otherwise quiet so there weren’t many issues to discuss.

In absence of many other pressing issues, we spent some time thinking ahead to large-scale development work that might take place in the 5.41 series. We talked about “hooks” as a potential long-term thought to making a more powerful Magic-like structure, for implementing new features, attributes, etc..

PEVANS Core Perl 5: Grant Report for February 2024

Perl Foundation News

Published by alh on Tuesday 05 March 2024 12:33


Paul writes:

``` Hours:

1 = Allow space in -M option https://github.com/Perl/perl5/pull/21935

3 = Tidy up / remove builtin unimport logic https://github.com/Perl/perl5/pull/22002 https://github.com/Perl/perl5/pull/22009

5.5 = use VERSION restrictions https://github.com/Perl/perl5/pull/21980 https://github.com/Perl/perl5/pull/21997 https://github.com/Perl/perl5/pull/22057

1 = class.c bugfix https://github.com/Perl/perl5/pull/21957

2 = builtin::numify https://github.com/Perl/perl5/pull/21982

1 = Tests for class.c non-ASCII UTF-8 https://github.com/Perl/perl5/pull/21983

1.5 = Logical xor operator (^^) https://github.com/Perl/perl5/pull/21996

Total: 15 hours. ```


Dave writes:

(this report covers two months)

This is my monthly report on work done during Jan,Feb 2024 covered by my TPF perl core maintenance grant.

I spent the last two months mainly on two goals.

1) Understanding XS better so that I can then decide how to update the XS ecosystem to better support a reference-counted stack; as an example, automatically removing the need to call XSUBs via a wrapper in some circumstances.

Doing this led me down a rabbit hole of realising how awful our current XS documentation is. Just about every section I read resulted in confusion, followed by time out to experiment and/or to look at the ParseXS src code to try to understand what the documentation was trying to tell me. It's also very out of date: telling us of exciting "new" features introduced 25 years ago.

The net result of this is that I now have about 1000 lines of notes on "things to fix in the XS docs". I intend sometime soon to completely revamp perlxs.pod and perlxstut.pod, based on these notes. Which is a bit of sidetrack from getting XS working better under PERL_RC_STACK builds. And doing PERL_RC_STACK was itself initially a sidetrack from doing more work on perl signatures. Such is often the way when working on perl.

2) General small tasks to help get blead into shape for the 5.40 release, such as analysing and reducing smoke failures, fixing bugs, and fixing any Deparse regressions that have crept in over the last year.

SUMMARY: * 0:38 #21822: BBC: Blead Breaks Variable::Magic * 1:20 #21876: BBC: 5.39.7 breaks GONZUS/Cache-utLRU-0.002000.tar.gz * 3:21 #21969: clone-with-stack.t crash * 2:17 fix Test -deparse failures * 1:35 fix minitest failures * 3:39 make __LINE__ etc Deparse batter * 1:57 make stack reference counted * 30:30 make stack reference counted - XS * 19:46 process p5p mailbox * 1:28 reduce build stderr noise * 8:33 reduce smoke failures

TOTAL: * 75:04 (HH::MM)

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1: Count Even Digits Number

You are given an array of positive integers, @ints. Write a script to find out how many integers have even number of digits.

The majory of the work can be done in a single line. Conveniently the tr function returns the number of characters effected by the command. For our purposes that means telling tr to delete all numerals. We then check if the number of numerals removed is even inside of a grep block. The number of matches is then returned. Note the one catch, in order to use tr we need to assign $_ to a temporary value, $x. Otherwise we would get an error Modification of a read-only value.

count even digits 1 ⟩≡


sub count_even_digits{
return 0 +
grep {
my $x = $_; $x =~ tr/[0-9]//d % 2 == 0
} @_;
}

Fragment referenced in 2.

The rest of the code just tests this function.

"perl/ch-1.pl" 2


preamble 3
count even digits 1
main 4

preamble 3 ⟩≡


use v5.38;

Fragment referenced in 2, 7.

main 4 ⟩≡


MAIN:{
say count_even_digits 10, 1, 111, 24, 1000;
say count_even_digits 111, 1, 11111;
say count_even_digits 2, 8, 1024, 256;
}

Fragment referenced in 2.

Sample Run
$ perl perl/ch-1.pl 
3 
0 
1
    

Part 2: Sum of Values

You are given an array of integers, @int and an integer $k. Write a script to find the sum of values whose index binary representation has exactly $k number of 1-bit set.

First, let’s concern ourselves with counting set bits. Here we can re-use some code that we’ve used before. This is a pretty standard way to count bits. This procedure is to do a bitwise AND operation for the least significant bit and check if it is set. We then right shift and repeat until no bits remain. This code is actually a modification of code used in TWC 079!

count set bits 5 ⟩≡


sub count_bits{
my($x) = @_;
my $total_count_set_bit = 0;
while($x){
my $b = $x & 1;
$total_count_set_bit++ if $b;
$x = $x >> 1;
}
return $total_count_set_bit;
}

Fragment referenced in 7.

With that necessary work taken care of we need to loop over the given array of integers and (1) check to see if the index contains the correct number of set bits and, if that is the case, add to the rolling sum. Finally, return the sum.

sum of value 6 ⟩≡


sub sum_of_values{
my $k = shift;
my(@n) = @_;
my $sum;
do{
$sum += $_[$_] if count_bits($_) == $k;
} for 0 .. @n - 1;
return $sum;
}

Fragment referenced in 7.

The rest of the code drives some tests.

"perl/ch-2.pl" 7


preamble 3
count set bits 5
sum of value 6
main 8

main 8 ⟩≡


MAIN:{
say sum_of_values 1, 2, 5, 9, 11, 3;
say sum_of_values 2, 2, 5, 9, 11, 3;
say sum_of_values 0, 2, 5, 9, 11, 3;
}

Fragment referenced in 7.

Sample Run
$ perl perl/ch-2.pl 
17 
11 
2
    

(cdlxxxv) 7 great CPAN modules released last week

Niceperl

Published by Unknown on Sunday 03 March 2024 08:47

Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. CGI - Handle Common Gateway Interface requests and responses
    • Version: 4.62 on 2024-03-01, with 43 votes
    • Previous CPAN version: 4.61 was 1 month, 24 days before
    • Author: LEEJO
  2. CPAN::Audit - Audit CPAN distributions for known vulnerabilities
    • Version: 20240302.001 on 2024-03-03, with 13 votes
    • Previous CPAN version: 20240215.001 was 16 days before
    • Author: BDFOY
  3. Date::Manip - Date manipulation routines
    • Version: 6.95 on 2024-03-01, with 19 votes
    • Previous CPAN version: 6.94 was 1 month, 23 days before
    • Author: SBECK
  4. Encode - character encodings in Perl
    • Version: 3.21 on 2024-02-25, with 61 votes
    • Previous CPAN version: 3.20 was 3 months, 15 days before
    • Author: DANKOGAI
  5. Excel::Writer::XLSX - Create a new file in the Excel 2007+ XLSX format.
    • Version: 1.12 on 2024-02-26, with 63 votes
    • Previous CPAN version: 1.11 was 11 months, 7 days before
    • Author: JMCNAMARA
  6. SPVM - SPVM Language
    • Version: 0.989082 on 2024-03-01, with 31 votes
    • Previous CPAN version: 0.989080 was 7 days before
    • Author: KIMOTO
  7. Sys::Virt - libvirt Perl API
    • Version: v10.1.0 on 2024-03-01, with 17 votes
    • Previous CPAN version: v10.0.0 was 1 month, 15 days before
    • Author: DANBERR

Perl Weekly Challenge 258: Sum of Values

blogs.perl.org

Published by laurent_r on Saturday 02 March 2024 16:07

These are some answers to the Week 258, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a couple of days from now (on March 3, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 2: Sum of Values

You are given an array of integers, @int and an integer $k.

Write a script to find the sum of values whose index binary representation has exactly $k number of 1-bit set.

Example 1

Input: @ints = (2, 5, 9, 11, 3), $k = 1
Output: 17

Binary representation of index 0 = 0
Binary representation of index 1 = 1
Binary representation of index 2 = 10
Binary representation of index 3 = 11
Binary representation of index 4 = 100

So the indices 1, 2 and 4 have total one 1-bit sets.
Therefore the sum, $ints[1] + $ints[2] + $ints[4] = 17

Example 2

Input: @ints = (2, 5, 9, 11, 3), $k = 2
Output: 11

Example 3

Input: @ints = (2, 5, 9, 11, 3), $k = 0
Output: 2

Sum of Values in Raku

Although it could easily be done in a one-liner, I've decided to split the solution in two statements, for the sake of clarity. The first statement finds the indexes whose binary representation contains exactly $k "1" (sum of digits equal to $k) and populates the @eligibles array with the corresponding input values in @in. The second statement simply returns the sum oh those values.

sub sum-of-values ($k, @in) {
    my @eligibles = map { @in[$_] }, 
        grep {$_.base(2).comb.sum == $k}, 0..@in.end;
    return @eligibles.sum;
}

my @tests = (1, <2 5 9 11 3>), 
            (2, <2 5 9 11 3>), 
            (0, <2 5 9 11 3>);

for @tests -> @test {
    printf "%-15s => ", "@test[]";
    say sum-of-values @test[0], @test[1];
}

This program displays the following output:

$ raku ./sum-of-values.raku
1 2 5 9 11 3    => 17
2 2 5 9 11 3    => 11
0 2 5 9 11 3    => 2

Sum of Values in Perl

This is a port to Perl of the above Raku program. I counted the number of "1" using the tr/// operator because has no built-in sum function, only to find moments later that I needed to implement a sum subroutine anyway.

use strict;
use warnings;
use feature 'say';

sub sum {
    my $sum = 0;
    $sum += $_ for @_;
    return $sum;
}

sub sum_of_values {
    my ($k, @in) = @_; 
    my @eligibles = map { $in[$_] } 
        grep {sprintf ("%b", $_) =~ tr/1/1/  == $k} 0..$#in;
    return sum @eligibles;
}

my @tests = ( [1, [<2 5 9 11 3>]], 
              [2, [<2 5 9 11 3>]], 
              [0, [<2 5 9 11 3>]] );

for my $test (@tests) {
    printf "%-3s - %-15s  => ", "$test->[0]", "@{$test->[1]}";
    say sum_of_values $test->[0], @{$test->[1]};
}

This program displays the following output:

$ perl ./sum-of-values.pl
1   - 2 5 9 11 3       => 17
2   - 2 5 9 11 3       => 11
0   - 2 5 9 11 3       => 2

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on March 10, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

List of new CPAN distributions – Feb 2024

Perlancar

Published by perlancar on Friday 01 March 2024 00:00

dist author abstract date
Acme-CPANModules-ArrayData PERLANCAR List of modules related to ArrayData 2024-02-05T00:05:46
Acme-CPANModules-FormattingDate PERLANCAR List of various methods to format dates 2024-02-18T14:01:27
Acme-CPANModules-HashData PERLANCAR List of modules related to HashData 2024-02-06T00:05:32
Acme-CPANModules-Import-CPANRatings-User-davidgaramond PERLANCAR List of modules mentioned by CPANRatings user davidgaramond 2024-02-28T00:05:24
Acme-CPANModules-InfoFromCPANTesters PERLANCAR List of distributions that gather information from CPANTesters 2024-02-18T14:03:11
Acme-CPANModules-InterestingTies PERLANCAR List of interesting uses of the tie() interface 2024-02-29T00:05:11
Acrux-DBI ABALAMA Database independent interface for Acrux applications 2024-02-05T18:44:46
Alien-Cowl ZMUGHAL Find or build Cowl 2024-02-15T03:24:53
Alien-Qhull DJERIUS Build and Install the Qhull library 2024-02-09T17:38:52
AnyEvent-Sway JOHNMERTZ communicate with the Sway window manager 2024-02-09T00:42:07
App-GnuCash-MembershipUtils PDURDEN A group of perl modules and scripts to help in using GnuCash for membership. 2024-02-27T02:41:31
App-ISBN-Check SKIM Tool for ISBN checking. 2024-02-25T18:59:34
App-MARC-Record-Stats SKIM Tool to work with MARC::Record::Stats on MARC dataset. 2024-02-21T11:20:06
App-MergeCal DAVECROSS 2024-02-02T17:37:26
App-Prove-Plugin-TestArgs SVW A prove plugin to configure test aliases and arguments 2024-02-07T12:49:02
App-cdbookmark PERLANCAR Change directory to one from the list 2024-02-03T00:05:45
App-grep-similar-text PERLANCAR Print lines similar to the specified text 2024-02-01T00:06:12
App-zen LITCHIE Zen is a markdown based literate programming tool 2024-02-05T05:48:06
Bencher-Scenarios-Log-Dispatch PERLANCAR Bencher scenarios related to Log::Dispatch modules 2024-02-04T00:05:28
Bencher-Scenarios-Log-Dispatch-FileRotate PERLANCAR Scenarios to benchmark Log::Dispatch::FileRotate 2024-02-11T00:05:41
Bundle-WATERKIP WATERKIP A mono repo for perl scripts and modules which WATERKIP likes 2024-02-27T23:00:33
Chess-ELO-FIDE NICEPERL Download and store FIDE ratings 2024-02-24T19:06:41
Common-Log-Parser RRWO Parse the common log format lines used by Apache 2024-02-09T15:12:27
Comparer PERLANCAR Reusable comparer subroutines 2024-02-08T00:11:13
Comparer-by_similarity PERLANCAR Compare similarity to a reference string 2024-02-23T02:06:32
Comparer-similarity PERLANCAR Compare similarity to a reference string 2024-02-24T00:06:09
DBIx-Class-FilterColumn-Encrypt LEONT Transparently encrypt columns in DBIx::Class 2024-02-03T15:22:04
Dancer2-Controllers RAWLEYFOW A tool to allow OO style route declaration in Dancer2 2024-02-14T22:00:57
Data-Login SKIM Data objects for login. 2024-02-05T22:13:16
Data-Sah-FilterBundle-Filename-Safe PERLANCAR Sah filters related to removing problematic characters from filename 2024-02-10T00:06:19
Data-Structure-Deserialize-Auto TYRRMINAL Deserializes data structures from perl, JSON, YAML, or TOML data, from strings or files 2024-02-22T18:13:45
Data-Text-Simple SKIM Data objects for text in language. 2024-02-29T17:29:50
Data-Transfigure TYRRMINAL performs rule-based data transfigurations of arbitrary structures 2024-02-19T20:39:03
Date-Holidays-CW WATERKIP Curacoa's official holidays 2024-02-08T07:49:12
Devel-Confess-Source-Patch-ExcludePackage PERLANCAR Exclude some packages from source trace 2024-02-25T00:05:42
Dist-Zilla-Plugin-GitHub-Offline LEONT Add a GitHub repo's info to META.{yml,json} 2024-02-06T19:19:02
File-Util-Rename PERLANCAR Utilities related to renaming files 2024-02-12T00:06:03
Games-Sudoku-Html SHE Visualize and play collections of standard 9×9 Sudoku in your browser. 2024-02-24T20:23:44
Games-Sudoku-Pdf SHE Produce pdf files from your digital Sudoku sources or collections. 2024-02-24T19:57:08
Locale-CLDR-Locales-Aa JGNI Locale::CLDR – Data Package ( Perl localization data for Afar ) 2024-02-25T13:32:59
Locale-CLDR-Locales-Ab JGNI Locale::CLDR – Data Package ( Perl localization data for Abkhazian ) 2024-02-25T13:34:25
Locale-CLDR-Locales-An JGNI Locale::CLDR – Data Package ( Perl localization data for Aragonese ) 2024-02-25T13:39:26
Locale-CLDR-Locales-Ann JGNI Locale::CLDR – Data Package ( Perl localization data for Obolo ) 2024-02-25T13:40:49
Locale-CLDR-Locales-Apc JGNI Locale::CLDR – Data Package ( ) 2024-02-25T13:42:12
Locale-CLDR-Locales-Arn JGNI Locale::CLDR – Data Package ( Perl localization data for Mapuche ) 2024-02-25T13:43:47
Locale-CLDR-Locales-Ba JGNI Locale::CLDR – Data Package ( Perl localization data for Bashkir ) 2024-02-25T13:49:23
Locale-CLDR-Locales-Bal JGNI Locale::CLDR – Data Package ( Perl localization data for Baluchi ) 2024-02-25T13:49:34
Locale-CLDR-Locales-Bew JGNI Locale::CLDR – Data Package ( Perl localization data for Betawi ) 2024-02-25T13:54:02
Locale-CLDR-Locales-Bgc JGNI Locale::CLDR – Data Package ( Perl localization data for Haryanvi ) 2024-02-25T13:56:59
Locale-CLDR-Locales-Bgn JGNI Locale::CLDR – Data Package ( Perl localization data for Western Balochi ) 2024-02-25T13:57:19
Locale-CLDR-Locales-Bho JGNI Locale::CLDR – Data Package ( Perl localization data for Bhojpuri ) 2024-02-25T13:58:45
Locale-CLDR-Locales-Blo JGNI Locale::CLDR – Data Package ( Perl localization data for Anii ) 2024-02-25T14:00:25
Locale-CLDR-Locales-Blt JGNI Locale::CLDR – Data Package ( Perl localization data for Tai Dam ) 2024-02-25T14:00:36
Locale-CLDR-Locales-Bss JGNI Locale::CLDR – Data Package ( Perl localization data for Akoose ) 2024-02-25T14:08:19
Locale-CLDR-Locales-Byn JGNI Locale::CLDR – Data Package ( Perl localization data for Blin ) 2024-02-25T14:08:31
Locale-CLDR-Locales-Cad JGNI Locale::CLDR – Data Package ( Perl localization data for Caddo ) 2024-02-25T14:11:41
Locale-CLDR-Locales-Cch JGNI Locale::CLDR – Data Package ( Perl localization data for Atsam ) 2024-02-25T14:11:52
Locale-CLDR-Locales-Cho JGNI Locale::CLDR – Data Package ( Perl localization data for Choctaw ) 2024-02-25T14:16:44
Locale-CLDR-Locales-Cic JGNI Locale::CLDR – Data Package ( Perl localization data for Chickasaw ) 2024-02-25T14:19:31
Locale-CLDR-Locales-Co JGNI Locale::CLDR – Data Package ( Perl localization data for Corsican ) 2024-02-25T14:21:02
Locale-CLDR-Locales-Csw JGNI Locale::CLDR – Data Package ( Perl localization data for Swampy Cree ) 2024-02-25T14:22:49
Locale-CLDR-Locales-Cv JGNI Locale::CLDR – Data Package ( Perl localization data for Chuvash ) 2024-02-25T14:25:39
Locale-CLDR-Locales-Dv JGNI Locale::CLDR – Data Package ( Perl localization data for Divehi ) 2024-02-25T14:35:09
Locale-CLDR-Locales-Frr JGNI Locale::CLDR – Data Package ( Perl localization data for Northern Frisian ) 2024-02-25T14:51:31
Locale-CLDR-Locales-Gaa JGNI Locale::CLDR – Data Package ( Perl localization data for Ga ) 2024-02-25T14:54:34
Locale-CLDR-Locales-Gez JGNI Locale::CLDR – Data Package ( Perl localization data for Geez ) 2024-02-25T14:57:36
Locale-CLDR-Locales-Gn JGNI Locale::CLDR – Data Package ( Perl localization data for Guarani ) 2024-02-25T14:59:14
Locale-CLDR-Locales-Hnj JGNI Locale::CLDR – Data Package ( Perl localization data for Hmong Njua ) 2024-02-25T15:09:00
Locale-CLDR-Locales-Ie JGNI Locale::CLDR – Data Package ( Perl localization data for Interlingue ) 2024-02-25T15:20:31
Locale-CLDR-Locales-Io JGNI Locale::CLDR – Data Package ( Perl localization data for Ido ) 2024-02-25T15:23:42
Locale-CLDR-Locales-Iu JGNI Locale::CLDR – Data Package ( Perl localization data for Inuktitut ) 2024-02-25T15:26:52
Locale-CLDR-Locales-Jbo JGNI Locale::CLDR – Data Package ( Perl localization data for Lojban ) 2024-02-25T15:28:43
Locale-CLDR-Locales-Kaj JGNI Locale::CLDR – Data Package ( Perl localization data for Jju ) 2024-02-25T15:34:54
Locale-CLDR-Locales-Kcg JGNI Locale::CLDR – Data Package ( Perl localization data for Tyap ) 2024-02-25T15:36:25
Locale-CLDR-Locales-Ken JGNI Locale::CLDR – Data Package ( Perl localization data for Kenyang ) 2024-02-25T15:39:38
Locale-CLDR-Locales-Kpe JGNI Locale::CLDR – Data Package ( Perl localization data for Kpelle ) 2024-02-25T15:51:57
Locale-CLDR-Locales-Kxv JGNI Locale::CLDR – Data Package ( Perl localization data for Kuvi ) 2024-02-25T15:59:25
Locale-CLDR-Locales-La JGNI Locale::CLDR – Data Package ( Perl localization data for Latin ) 2024-02-25T16:01:00
Locale-CLDR-Locales-Lij JGNI Locale::CLDR – Data Package ( Perl localization data for Ligurian ) 2024-02-25T16:05:34
Locale-CLDR-Locales-Lmo JGNI Locale::CLDR – Data Package ( Perl localization data for Lombard ) 2024-02-25T16:07:06
Locale-CLDR-Locales-Mdf JGNI Locale::CLDR – Data Package ( Perl localization data for Moksha ) 2024-02-25T16:18:24
Locale-CLDR-Locales-Mic JGNI Locale::CLDR – Data Package ( Perl localization data for Mi'kmaw ) 2024-02-25T16:25:46
Locale-CLDR-Locales-Moh JGNI Locale::CLDR – Data Package ( Perl localization data for Mohawk ) 2024-02-25T16:30:37
Locale-CLDR-Locales-Mus JGNI Locale::CLDR – Data Package ( Perl localization data for Muscogee ) 2024-02-25T16:35:33
Locale-CLDR-Locales-Myv JGNI Locale::CLDR – Data Package ( Perl localization data for Erzya ) 2024-02-25T16:38:20
Locale-CLDR-Locales-Nqo JGNI Locale::CLDR – Data Package ( Perl localization data for N’Ko ) 2024-02-25T16:49:31
Locale-CLDR-Locales-Nr JGNI Locale::CLDR – Data Package ( Perl localization data for South Ndebele ) 2024-02-25T16:49:40
Locale-CLDR-Locales-Nso JGNI Locale::CLDR – Data Package ( Perl localization data for Northern Sotho ) 2024-02-25T16:51:06
Locale-CLDR-Locales-Nv JGNI Locale::CLDR – Data Package ( Perl localization data for Navajo ) 2024-02-25T16:52:52
Locale-CLDR-Locales-Ny JGNI Locale::CLDR – Data Package ( Perl localization data for Nyanja ) 2024-02-25T16:54:29
Locale-CLDR-Locales-Oc JGNI Locale::CLDR – Data Package ( Perl localization data for Occitan ) 2024-02-25T16:56:13
Locale-CLDR-Locales-Osa JGNI Locale::CLDR – Data Package ( Perl localization data for Osage ) 2024-02-25T16:59:38
Locale-CLDR-Locales-Pap JGNI Locale::CLDR – Data Package ( Perl localization data for Papiamento ) 2024-02-25T17:02:20
Locale-CLDR-Locales-Pis JGNI Locale::CLDR – Data Package ( Perl localization data for Pijin ) 2024-02-25T17:04:08
Locale-CLDR-Locales-Quc JGNI Locale::CLDR – Data Package ( Perl localization data for Kʼicheʼ ) 2024-02-25T17:10:41
Locale-CLDR-Locales-Raj JGNI Locale::CLDR – Data Package ( Perl localization data for Rajasthani ) 2024-02-25T17:10:54
Locale-CLDR-Locales-Rhg JGNI Locale::CLDR – Data Package ( Perl localization data for Rohingya ) 2024-02-25T17:12:17
Locale-CLDR-Locales-Rif JGNI Locale::CLDR – Data Package ( Perl localization data for Riffian ) 2024-02-25T17:13:41
Locale-CLDR-Locales-Scn JGNI Locale::CLDR – Data Package ( Perl localization data for Sicilian ) 2024-02-25T17:27:35
Locale-CLDR-Locales-Sdh JGNI Locale::CLDR – Data Package ( Perl localization data for Southern Kurdish ) 2024-02-25T17:29:16
Locale-CLDR-Locales-Shn JGNI Locale::CLDR – Data Package ( Perl localization data for Shan ) 2024-02-25T17:36:55
Locale-CLDR-Locales-Sid JGNI Locale::CLDR – Data Package ( Perl localization data for Sidamo ) 2024-02-25T17:37:33
Locale-CLDR-Locales-Skr JGNI Locale::CLDR – Data Package ( ) 2024-02-25T17:40:13
Locale-CLDR-Locales-Sma JGNI Locale::CLDR – Data Package ( Perl localization data for Southern Sami ) 2024-02-25T17:41:45
Locale-CLDR-Locales-Smj JGNI Locale::CLDR – Data Package ( Perl localization data for Lule Sami ) 2024-02-25T17:43:11
Locale-CLDR-Locales-Sms JGNI Locale::CLDR – Data Package ( Perl localization data for Skolt Sami ) 2024-02-25T17:45:00
Locale-CLDR-Locales-Ss JGNI Locale::CLDR – Data Package ( Perl localization data for Swati ) 2024-02-25T17:49:56
Locale-CLDR-Locales-Ssy JGNI Locale::CLDR – Data Package ( Perl localization data for Saho ) 2024-02-25T17:51:22
Locale-CLDR-Locales-St JGNI Locale::CLDR – Data Package ( Perl localization data for Southern Sotho ) 2024-02-25T17:51:52
Locale-CLDR-Locales-Syr JGNI Locale::CLDR – Data Package ( Perl localization data for Syriac ) 2024-02-25T17:56:10
Locale-CLDR-Locales-Szl JGNI Locale::CLDR – Data Package ( Perl localization data for Silesian ) 2024-02-25T17:57:55
Locale-CLDR-Locales-Tig JGNI Locale::CLDR – Data Package ( Perl localization data for Tigre ) 2024-02-25T18:04:08
Locale-CLDR-Locales-Tn JGNI Locale::CLDR – Data Package ( Perl localization data for Tswana ) 2024-02-25T18:07:12
Locale-CLDR-Locales-Tok JGNI Locale::CLDR – Data Package ( Perl localization data for Toki Pona ) 2024-02-25T18:08:49
Locale-CLDR-Locales-Tpi JGNI Locale::CLDR – Data Package ( Perl localization data for Tok Pisin ) 2024-02-25T18:09:03
Locale-CLDR-Locales-Trv JGNI Locale::CLDR – Data Package ( Perl localization data for Taroko ) 2024-02-25T18:13:13
Locale-CLDR-Locales-Trw JGNI Locale::CLDR – Data Package ( Perl localization data for Torwali ) 2024-02-25T18:13:24
Locale-CLDR-Locales-Ts JGNI Locale::CLDR – Data Package ( Perl localization data for Tsonga ) 2024-02-25T18:15:02
Locale-CLDR-Locales-Tyv JGNI Locale::CLDR – Data Package ( Perl localization data for Tuvinian ) 2024-02-25T18:18:06
Locale-CLDR-Locales-Ve JGNI Locale::CLDR – Data Package ( Perl localization data for Venda ) 2024-02-25T18:24:31
Locale-CLDR-Locales-Vec JGNI Locale::CLDR – Data Package ( Perl localization data for Venetian ) 2024-02-25T18:25:52
Locale-CLDR-Locales-Vmw JGNI Locale::CLDR – Data Package ( Perl localization data for Makhuwa ) 2024-02-25T18:28:42
Locale-CLDR-Locales-Wa JGNI Locale::CLDR – Data Package ( Perl localization data for Walloon ) 2024-02-25T18:30:55
Locale-CLDR-Locales-Wal JGNI Locale::CLDR – Data Package ( Perl localization data for Wolaytta ) 2024-02-25T18:33:42
Locale-CLDR-Locales-Wbp JGNI Locale::CLDR – Data Package ( Perl localization data for Warlpiri ) 2024-02-25T18:33:50
Locale-CLDR-Locales-Xnr JGNI Locale::CLDR – Data Package ( Perl localization data for Kangri ) 2024-02-25T18:37:03
Locale-CLDR-Locales-Za JGNI Locale::CLDR – Data Package ( Perl localization data for Zhuang ) 2024-02-25T18:44:50
Microsoft-Teams-WebHook TYRRMINAL Microsoft Teams WebHook with AdaptiveCards for formatting notifications 2024-02-20T19:13:14
Mo-utils-IRI SKIM Mo utilities for IRI. 2024-02-29T21:11:02
Mo-utils-URI SKIM Mo utilities for URI. 2024-02-11T16:17:45
Mojolicious-Plugin-INIConfig-Extended HESCO Mojolicious Plugin to overload a Configuration 2024-02-13T02:33:46
Mojolicious-Plugin-WebComponent RES An effort to make creating and using custom web components easier 2024-02-29T16:06:39
Net-EANSearch JANW Perl module for EAN and ISBN lookup and validation using the API on https://www.ean-search.org 2024-02-13T15:30:27
PDL-Opt-GLPK SOMMREY PDL interface to the GNU Linear Programming Kit 2024-02-21T20:32:39
Perlgram-Bot AMIRCANDY 2024-02-26T10:23:19
Plack-App-ChangePassword SKIM Plack change password application. 2024-02-08T21:15:14
Pod-Weaver-Plugin-Sah-SchemaBundle PERLANCAR Plugin to use when building Sah::SchemaBundle::* distribution 2024-02-26T00:06:02
RDF-Cowl ZMUGHAL A lightweight API for working with OWL 2 ontologies 2024-02-15T03:37:41
SPVM-HTTP-Tiny KIMOTO HTTP Client 2024-02-23T08:53:30
Sah-Schemas-Comparer PERLANCAR Sah schemas related to Comparer 2024-02-16T00:06:37
Sah-Schemas-SortKey PERLANCAR Sah schemas related to SortKey 2024-02-18T14:01:38
Sort-BySimilarity PERLANCAR Sort by most similar to a reference string 2024-02-02T00:05:29
SortExample PERLANCAR Sort examples 2024-02-27T00:05:08
SortKey PERLANCAR Reusable sort key generators 2024-02-14T00:05:41
SortKey-Num-by_length PERLANCAR String length as sort key 2024-02-15T00:05:40
SortKey-Num-length PERLANCAR String length as sort key 2024-02-15T00:05:51
Sorter PERLANCAR Sorter 2024-02-07T00:11:23
Sorter-by_similarity PERLANCAR Sort by most similar to a reference string 2024-02-13T00:06:16
Tags-HTML-ChangePassword SKIM Tags helper for change password. 2024-02-07T20:04:02
Tie-Hash-HashData PERLANCAR Access HashData object as a tied hash 2024-02-09T00:05:25
Tk-AppWindow HANJE an application framework based on Tk 2024-02-28T15:29:57
WWW-Suffit-Plugin-ConfigAuth ABALAMA The Suffit plugin for authentication and authorization providing via configuration 2024-02-22T08:17:35
WWW-Suffit-Plugin-FileAuth ABALAMA The Suffit plugin for authentication and authorization by password file 2024-02-22T11:39:04
WWW-Suffit-Plugin-SuffitAuth ABALAMA The Suffit plugin for Suffit API authentication and authorization providing 2024-02-22T08:16:09
mojo-util-benchmark CRLCU A set of utilities for working with collections of data. 2024-02-07T13:49:03

Stats

Number of new CPAN distributions this period: 155

Number of authors releasing new CPAN distributions this period: 26

Authors by number of new CPAN distributions this period:

No Author Distributions
1 JGNI 88
2 PERLANCAR 27
3 SKIM 8
4 ABALAMA 4
5 TYRRMINAL 3
6 SHE 2
7 LEONT 2
8 ZMUGHAL 2
9 WATERKIP 2
10 LITCHIE 1
11 AMIRCANDY 1
12 HANJE 1
13 RAWLEYFOW 1
14 JOHNMERTZ 1
15 CRLCU 1
16 DJERIUS 1
17 JANW 1
18 SVW 1
19 PDURDEN 1
20 RES 1
21 HESCO 1
22 NICEPERL 1
23 SOMMREY 1
24 KIMOTO 1
25 RRWO 1
26 DAVECROSS 1

The present isn’t evenly distributed either

Perl Hacks

Published by Dave Cross on Saturday 24 February 2024 15:22

The future is already here – it’s just not very evenly distributed
– William Gibson

The quotation above was used by Tim O’Reilly a lot around the time that Web 2.0 got going. Over recent months, I’ve had a few experiences that have made it clear to me that even the present isn’t particularly evenly distributed either. It’s always easy to find people still using technologies that we would consider archaic (and not in a rustic or hipster way).

We’ve known for twenty years that CGI is a bad idea. It’s almost ten years since CGI.pm was removed from Perl core. Surely, all of us are using something modern for web development these days.

Well, apparently not. CGI is alive and well and living on the fringes of the Perl community. I’ve come across it being used in some quite surprising places over the last year or so. I’m going to obfuscate some details in the following descriptions to, hopefully, prevent you (or, worse, the people involved) from recognising the companies involved.

  • I did some work for a spectacularly big (and I mean huge) consultancy company. They wanted to decommission some old servers – which involved moving some Perl CGI programs that no-one had looked at for about fifteen years. These programs were, of course, running vital bits of the business. Anyone who had ever edited them had left the company at least ten years earlier. They wanted to do it as quickly as possible and change as little of the code as possible. The code was incompatible with even vaguely modern versions of Perl, so much of the work involved installing old versions of Perl (along with Apache and even mod_perl) on new hardware running up-to-date operating systems.
  • I picked up two or three freelancing gigs on Fiverr. And for the first time in years, I found myself working with low-end, rented, shared servers. At least one of them was one of those situations where you don’t have root access and are extremely hampered by the lack of software.
  • A couple of weeks ago, I got an email to my SourceForge email address asking for help with nms Formmail (some readers may be young enough that they haven’t heard of Matt’s Script Archive or the London Perl Mongers rewrite of those programs into what we called “modern Perl” twenty years ago). The email asked if our Formmail supported anti-spam measures like SPF, DMARC and DKIM. It was nostalgic to recall how different the web was back in the days when every web site had a mail form, a guest book and a hit counter. I see that SourceForge have removed the nms web site. I doubt I’ll ever get the time to work out what happened to it.  [Update: I was wrong about that. It’s been so long since I’ve looked at the nms project that I had forgotten the URL. The web site is still there in all its early-2000s car-crash web design glory.]
  • The following day I saw a question on Stack Overflow about a “classic mailing script”. And, yes, it was nms Formmail again. This user had moved their web site to a new server and it had stopped working. We never got the error log content that we asked them for, but the user confirmed my suspicion that the new web server had a newer version of Perl – one that was released after CGI.pm was removed. The nms project had (for obvious reasons) made heavy use of the module and its removal from core Perl has rendered the nms programs unusable on cheap servers where the sysadmin has no knowledge of or interest in installing any Perl modules that aren’t part of the standard package. Sadly, this means that Matt Wright’s original versions (that were never updated to use CGI.pm) still work in environments where the nms versions are useless.

None of this should be taken as an argument that the nms project was wrong to use CGI.pm or that the Perl 5 Porters were wrong to remove it from the Perl standard library. I still support both decisions. I just found it a bit jarring to be reminded that while we’re all using PSGI or Mojolicious to write microservices in Perl that serve REST APIs that are developed and deployed in Docker containers, there are still people out there who are struggling to FTP code that was written in 1997 onto low-end shared hosting.

I think this state of affairs has two causes. Firstly (like the first client I mentioned above) some systems were set up when CGI was still in common use – and things haven’t changed since. These people get a sudden shock when they are forced to move to a more modern server for some reason. And then there are people like my Fiverr clients who install Perl CGI programs because that’s what they have always done and they don’t know that there is an alternative approach. Part of the problem there is, presumably, that Perl has meant badly-written CGI programs for a large proportion of the web’s existence and means anyone searching for information on this subject is likely to find pages and pages of advice telling them how to install CGI programs before they discover anything about PSGI or Docker. And I think there might be a solution to that problem (or, at least, a way to nudge the web in the right direction).

Over last weekend I was cataloguing subdomains (I know how to have fun!) and I found a web site that I had forgotten about. I had obviously been contemplating a very similar situation back in 2016.

The site is called Perl Web Advice. The intention was (is?) that it would be a definitive source of good advice about how to develop and deploy web applications written in Perl. I had only made tiny inroads into the task before something else apparently seemed more fun and the project was abandoned.

But there’s the start of a framework for the site. And, this week, I’ve given it a GitHub Actions workflow so it gets republished automatically whenever changes are pushed to the repo. I’ve even set up a Dockerfile to make it easy to use the static site generator that I’ve used for it. So perhaps the idea has merit. Once there’s a bit more useful content there I could see if I can remember any of my SEO knowledge and get it appearing in results where people are looking for advice on this topic.

I would, of course, be happy to consider contributions from other people. What do you think? Would you like to help me save people from the hell of CGI deployments?

The post The present isn’t evenly distributed either appeared first on Perl Hacks.

Convert Markdown to HTML

Perl Maven

Published by Gabor Szabo on Thursday 22 February 2024 10:30

I have lots of documents written in Markdown format and I was looking for a way to convert them to HTML.

Nominate heroes for the 2024 White Camel Awards

Perl Foundation News

Published by Makoto Nozaki on Wednesday 21 February 2024 17:20

We are seeking nominations for the 2024 White Camel Awards, which honor remarkable non-technical contributions in the Perl community. The Board will consider all nominations and will seek input both from the Advisory Board and the Perl Steering Council.

To nominate an individual, kindly complete the form at https://forms.gle/xQczcsRkguvaBDBn8.

In light of our community’s growing diversity, we kindly ask that the rationale for each nomination be articulated in a manner accessible to those who may not be familiar with the nominee.

For reference, previous recipients of this award can be found at https://whitecamel.org/.