How to use OpenMP from Perl with SPVM.

dev.to #perl

Published by Yuki Kimoto - SPVM Author on Thursday 28 March 2024 00:10

How to use OpenMP from Perl with SPVM.

See an example to bind OpenMP to SPVM

SPVM provides a way to bind C language libraries and call them from Perl.

When binding C libraries to Perl, you typically write XS, but SPVM offers an alternative approach.

MyOpenMP.spvm

class MyOpenMP {

  native static method sum_vec_int : int[] ($nums1 : int[], $nums2 : int[]);

  static method test : void () {
    my $nums1 = [1, 2, 3];
    my $nums2 = [5, 6, 7];

    my $nums3 = &sum_vec_int($nums1, $nums2);

    for (my $i = 0; $i < @$nums3; $i++) {
      say $nums3->[$i];
    }
  }
}

MyOpenMP.c

#include "spvm_native.h"

#include <string.h>

static const char* FILE_NAME = "SPVM/MyOpenMP.c";

int32_t SPVM__MyOpenMP__sum_vec_int(SPVM_ENV* env, SPVM_VALUE* stack) {

  void* obj_nums1 = stack[0].oval;
  if (obj_nums1 == NULL) {
    return env->die(env, stack, "$nums1 must be defined.", __func__, FILE_NAME, __LINE__);
  }
  int32_t* nums1 = env->get_elems_int(env, stack, obj_nums1);

  void* obj_nums2 = stack[1].oval;
  if(obj_nums2 == NULL) {
    return env->die(env, stack, "$nums2 must be defined.", __func__, FILE_NAME, __LINE__);
  }
  int32_t* nums2 = env->get_elems_int(env, stack, obj_nums2);

  int32_t length = env->length(env, stack, obj_nums1);

  void* obj_nums3 = env->new_int_array(env, stack, length);
  int32_t* nums3 = env->get_elems_int(env, stack, obj_nums3);

  int32_t i;
#pragma omp parallel for
  for (i = 0; i < length; i++) {
    nums3[i] = nums1[i] + nums2[i];
  }

  stack[0].oval = obj_nums3;

  return 0;
}

MyOpenMP.config

use strict;
use warnings;

use SPVM::Builder::Config;

my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);

# Compiler options
$config->add_ccflag('-fopenmp');

# Linker option
$config->add_ldflag('-fopenmp');
$config->add_lib('gomp');

$config;

openmp.pl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";

use SPVM 'MyOpenMP';

SPVM::MyOpenMP->test;

This program outputs values calculated by OpenMP.

6
8
10

Perl Weekly Challenge 262: Count Equal Divisible

blogs.perl.org

Published by laurent_r on Wednesday 27 March 2024 23:33

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

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on March 31, 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: Count Equal Divisible

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

Write a script to return the number of pairs (i, j) where

a) 0 <= i < j < size of @ints

b) ints[i] == ints[j]

c) i x j is divisible by k

Example 1

Input: @ints = (3,1,2,2,2,1,3) and $k = 2
Output: 4

(0, 6) => ints[0] == ints[6] and 0 x 6 is divisible by 2
(2, 3) => ints[2] == ints[3] and 2 x 3 is divisible by 2
(2, 4) => ints[2] == ints[4] and 2 x 4 is divisible by 2
(3, 4) => ints[3] == ints[4] and 3 x 4 is divisible by 2

Example 2

Input: @ints = (1,2,3) and $k = 1
Output: 0

Note that we need to make sure that the input integer $k is not zero.

Count Equal Divisible in Raku

We need two nested loops to manage (i, j) pairs. Property (a) is guaranteed by a proper choice of the ranges for the loop variables. The rest of the program is straight forward.

sub count-equal-div ($divisor where * != 0, @in) {
    my $count = 0;
    for 0..^@in.end -> $i {
        for $i^..@in.end -> $j {
            next if @in[$i] != @in[$j];
            $count++ if $i * $j %% $divisor;
        }
    }
    return $count;
}

my @tests = (2, (3,1,2,2,2,1,3)), (1, (1,2,3));
for @tests -> @test {
    printf "%d - %-15s => ", @test[0], "@test[1]";
    say count-equal-div @test[0], @test[1];
}

This program displays the following output:

$ raku ./count-equal-divisible.raku
2 - 3 1 2 2 2 1 3   => 4
1 - 1 2 3           => 0

Count Equal Divisible in Perl

This is a port to Perl of the above Raku program.

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

sub count_equal_div {
    my $divisor = shift;
    die "$divisor cannot be 0" if $divisor == 0;
    my @in = @_;
    my $count = 0;
    for my $i (0 .. $#in - 1) {
        for my $j ($i+1 .. $#in) {
            next if $in[$i] != $in[$j];
            $count++ if $i * $j % $divisor == 0;
        }
    }
    return $count;
}

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

This program displays the following output:

$ perl ./count-equal-divisible.pl
2 - 3 1 2 2 2 1 3   => 4
1 - 1 2 3           => 0

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 April 7, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

The Perl and Raku Conference

r/perl

Published by /u/nahthanxx on Wednesday 27 March 2024 21:11

The Perl and Raku Conference (formerly known 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!)

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

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

The Net::DNS version is 1.22.


I'm playing around with Net::DNS::RR and I am a bit confused about some random characters appearing in the output of DS records when I call Net::DNS::RR->string(or Net::DNS::RR->print). The output for Net::DNS::RR->plain is what I expected.

#!/usr/bin/perl

use strict;
use warnings; 

use Net::DNS; 

my @rr = rr("gov.uk", "DS");
print STDERR $_->plain . "\n" foreach (@rr);
print STDERR $_->string . "\n" foreach (@rr);

The output is as follows:

gov.uk. 300 IN DS 17539 8 2 2f0a0a65db9e930f5b2c0425f67df66416c076124652a281d9a8ffa773828f57
gov.uk. 300 IN DS 695 8 2 7277592dbd8993bde70704dbabd30afdbb85057e658ef1428f18f5d9a534bce0
gov.uk. 300     IN      DS      ( 17539 8 2
        2f0a0a65db9e930f5b2c0425f67df66416c076124652a281d9a8ffa773828f57 )
        ; xerob-pidyk-hukan-vagab-zokod-seced-hetal-tutok-gohys-bityc-ducih-demom-cekup-mazip-lasem-difoh-lixex
gov.uk. 300     IN      DS      ( 695 8 2
        7277592dbd8993bde70704dbabd30afdbb85057e658ef1428f18f5d9a534bce0 )
        ; xisil-lykud-tazum-nagar-tynib-licot-repat-fydoz-tivam-hicul-vunim-vosag-dofic-metyt-nunuf-gezev-byxex

As one can see, the plain response is as expected, meanwhile the string output has a bunch of seemingly random characters after the record (xerob-pidyk-huk...).

Can anyone shed light on what's happening here?

Regex for deconstructing SQL where statement

Perl questions on StackOverflow

Published by niebyl2002 on Wednesday 27 March 2024 14:45

Looking for a fancy regex to split partial SQL where statement. Legacy app is quite old and records below are manually entered, which allows for a lot of mistakes. Given below where code I need to split it by brackets. I also need to record logical operator so after processing each statement I could construct it back.

SQL where scenarios:

my $view2 = "test1=1 AND ( test2=2 ) AND (test3=4 OR test3=9 OR test3=3 OR test3=5)"
EXPECTED array:
1: "test1=1"
2: "test2=2"
3: "test3=4 OR test3=9 OR test3=3 OR test3=5"

my $view2 = "( test1=2 AND test2=1 ) OR ( test1=2 AND test2=6 ) OR ( test1=2 AND test2=8 ) OR ( test1=2 AND test2=10 )"
EXPECTED array:
1: "test1=2 AND test2=1"
2: "test1=2 AND test2=6"
3: "test1=2 AND test2=8"
4: "test1=2 AND test2=10"

my $view3 = "test1 = '1' AND test3 = '3'"
EXPECTED array:
1: "test1 = '1' AND test3 = '3'"

I've tried splitting each statement and logic separately, one array with sql code, another array with logic operators. I also tried one array with sql code and logical operators. If code is wrapped properly in brackets, all is working ($view2) but if its not then that part is omitted ($view1 and $view3).

This is what I have so far

my $view1 = "test1=1 AND ( test2=2 ) AND (test3=4 OR test3=9 OR test3=3 OR test3=5)";
my $view2 = "( test1=2 AND test2=1 ) OR ( test1=2 AND test2=6 ) OR ( test1=2 AND test2=8 ) OR ( test1=2 AND test2=10 )";
my $view3 = "test1 = '1' AND test3 = '3'";

# stmt and logic separated
my @arr = ( $view1 =~ /\([^)]*\)/g );
my @logic= ( $view1 =~ /\)[^)]*\(/g );

# stmt and logic in one array
my @arrOne = $view =~ /\([^)]*[^(]*\)|\w+/g;


my $counter = 1;
foreach my $record (@arr) {
    $record =~ s/\( | \)//g;
    print "\n" . $counter . ":";
    print $record;
    $counter += 1;
}

my $counter_logic = 1;
foreach my $record (@logic) {
    $record =~ s/\) | \(//g;
    print "\n";
    print $record;
}

How can I add part of sql code without brackets to regex pattern? Not sure if it's even doable? Any idea how to achieve it?

I want to convert "2024032615:34:00" to seconds in perl. Preferably, I want to have it converted using unix command/s (system command), as OS of machines on which the command to convert the time to seconds would run is of different version (One has RHEL 6.5 and other have RHEL 7.4, and thus also different version of perl)

How can i get the specified time 2024032615:34:00 (this is what I am fetching after some processing) in seconds?

I have a tool, expandfile, written in Perl, that can iterate over rows from an SQL query.

After upgrading to Sonoma, expandfile still worked, using Perl 5.30. I dumped my MySQL database to a text file.

Then I stupidly typed "brew update ImageMagick" and lots of programs were upgraded, including Perl and MySQL. I am having trouble getting expandfile to access SQL.

I updated my environment vars to change PERL5LIB to refer to the new version of Perl, 5.38.2. (I checked and $ARCHFLAGS from Ventura was still "-arch arm64" on this M2 Air.)

Homebrew installed MySQL Server version 8.3.0, so I configured MySQL, reloaded my dump, and set up '.my.cnf'. Data came back fine, as expected... checked from the command line tool.

Then I typed "expandfile" and got the error that Perl module LWP was missing (as were all other CPAN modules). This is what I expected: I always have to re-install CPAN modules after major macOS upgrades. (I did 'sudo -H cpan' and got a message that I had to execute 'o conf init pushy_https', so I did, and 'o conf commit'.) Then I did a long sequence of 'sudo -H cpanm install xxx' to reinstall about 40 CPAN modules. (A few CPAN modules had install errors due to missing prerequisites, fixed.)

I always do DBI and DBD::mysql last, because extra configuration is needed and sometimes there are problems. When I did "sudo -H cpanm install DBD::mysql" I got the message:

installing DBD::mysql failed installing DBD::mysql
DVEEDEN/DBD-mysql-5.004.tar.gz : writemakefile NO '/opt/homebrew/Cellar/perl/5.38.2_1/bin/perl Makefile.PL --testuser=root --testpass=xxx' returned status 512

I looked in .cpanm/work/number.number and found the build log for DBD::mysql. It got as far as {:Running Makefile.PL:} and failed with "Can't link/include C library 'zstd', 'ssl', 'crypto', aborting." Never saw this before.

I tried setting some configure-args: sudo cpanm --configure-args="--libs='-L/opt/homebrew/Cellar/openssl@3/3.2.1/lib -L/opt/homebrew/Cellar/zstd/1.5.5/lib'" install DBD::mysql

That got further, but still fails. The log has 269 warnings about macros, and then finally says "compilation failed, bailout called"

Failed test 'use DBD::mysql;'
at t/00base.t line 15.
Tried to use 'DBD::mysql'.
Error:  Can't load '...mysql.bundle' for module DBD::mysql: dlopen(../blib/arch/auto/DBD/mysql/mysql.bundle, 0x0002):
symbol not found in flat namespace '_mysql_affected_rows' at /opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level/DynaLoader.pm line 210. at t/00base.t line 15.

I must have missed a step somewhere.. but I thought I did the same steps that worked last time. Do I need something else in configure-args?

fix core-cpan-diff and sync-with-cpan to handle dist files with v prefixed versions

Allow a v prefix on versions expected by the core-cpan-diff and
sync-with-cpan scripts. Also align the two scripts with each other, and
handle the same file extensions expected by PAUSE.

Hotel hotspot hijinks

perl.com

Published on Tuesday 26 March 2024 18:00

Ever been staying at a hotel and gotten annoyed that you always have to open a browser to log in for wireless access? Yup, me too. A recent instance was particularly frustrating and I had to pull out my favourite Swiss Army chainsaw in order to make my life a bit easier.

The situation

So, the background story is that I was staying at a hotel in the mountains for a few days. As is the fortunate case these days1, the hotel had wireless access. The weird part, though, was that each room had a separate username and password. “Fair enough”, I thought and promptly opened my laptop and then Firefox to enter my login data to get the dearly-awaited connectivity. Using Firefox (or any other browser for that matter) was necessary because the login page was accessed via a captive portal. That’s the thing you get directed through when you see a login banner like this pop up in your browser:

Firefox captive portal login banner

That’s fine, I thought, and went merrily on with my day.

The problem

The problem started the following day. After getting up and waking up my laptop, I wasn’t able to read my email2, or read chat on irc3, see my messages via Signal, or use the internet at all4.

Also, ping greeted me with Destination Net Prohibited:

$ ping www.heise.de
PING www.heise.de (193.99.144.85) 56(84) bytes of data.
From logout.hotspot.lan (192.168.168.1) icmp_seq=1 Destination Net Prohibited
From logout.hotspot.lan (192.168.168.1) icmp_seq=2 Destination Net Prohibited
From logout.hotspot.lan (192.168.168.1) icmp_seq=3 Destination Net Prohibited
^C
--- www.heise.de ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2002ms

Obviously, I wasn’t online.

That’s when I noticed the Firefox captive portal login banner (see image above) again. Oh, I have to log in again, that’s weird. Upon clicking on the “Open Network Login Page” button, I was logged in automatically. No need to enter the login details again. That’s also weird, I thought, because if the login is automatic, why do I have to visit the login page again at all?

I put my laptop to sleep to go for a walk around the village, get some groceries, and enjoy the mountain air5. Upon my return, I had to log in again to get wireless access. I was slowly starting to get a bit miffed. My guess is that the MAC address from the relevant end-user device is removed from the access list fairly quickly, perhaps on the order of an hour or two6, and thus network connectivity is cut rather promptly.

One issue that made my situation even worse is that I often have several browser windows open at the same time; usually because I have several trains of thought on the go at once and each window contains information relevant to each train of thought. The thing is, only one of the browser windows actually shows the (automatically appearing) captive portal login banner. Finding the window with the banner was rather time consuming.

Ok, this was starting to get silly and a bit annoying. Time to automate the annoyance away. WWW::Mechanize to the rescue!

WWW::Mechanize as a comic book super hero; generated by DALL-E
WWW::Mechanize as a comic book super hero; generated by DALL-E.

The solution

Why choose WWW::Mechanize? Well, I’ve got experience with it (I used to use a similar process to automatically log in to the ICE train in Germany when I used to commute to work before the pandemic), I know I can use it to submit data into simple HTML forms, and Perl is my go-to language for this kind of automation.

So, how to get started with automating the login process? The simple solution: quit Firefox so that all browser windows are closed, put the computer to sleep and then go for a walk for a couple of hours.

Upon my return, I just needed to use a combination of perl -de0 to start a REPL-like environment to play around in and perldoc to read the extensive WWW::Mechanize documentation.

The first attempt at trying to trigger a connection to the captive portal didn’t go well:

└> perl -de0

Loading DB routines from perl5db.pl version 1.55
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(-e:1):   0
  DB<1> use WWW::Mechanize;

  DB<2> $mech = WWW::Mechanize->new;

  DB<3> $mech->get('https://google.com');

Error GETing https://google.com: Can't connect to google.com:443 (SSL
connect attempt failed) at (eval
22)[/home/cochrane/perl5/perlbrew/perls/perl-5.30.1/lib/5.30.1/perl5db.pl:738]
line 2.

Ok, so we need to use HTTP and avoid HTTPS. Good to know.

Just using HTTP worked much better:

  DB<4> x $mech->get('http://google.com')
0  HTTP::Response=HASH(0x55a95f5048c0)
<snip>
lots of details; you really don't want to see this
</snip>

That’s what we like to see! We’re at least getting stuff back now. Having a look at the page’s title, we get:

  DB<5> x $mech->title();
0  'myadvise hotspot > login'

Yup, that’s a login page. Dumping the page’s content with

  DB<5> x $mech->content();
<snip>
lots of HTML content
</snip>

we get to see what we’ve got to play with. The main things to note about the content (which I’m not showing because it’s too much detail and I want to protect the innocent) are:

  • we have a form called login

    <form name="login" action="http://login.hotspot.lan/login" method="post">
  • we have a username field with the name username

    <input style="width: 80px" name="username" type="text" value=""/>
  • and we have a password field with the name password

    <input style="width: 80px" name="password" type="password"/>

This gives us enough information to be able to submit the form using the relevant login data.

Aside: interestingly enough, the fields are in English even though the site is a German one. I guess standardising the fields on English can be useful when programming.

To submit the form, we use WWW::Mechanize’s submit_form() method (the call to which I’ve formatted nicely here to make things easier to read):

$mech->submit_form(
    form_name => 'login',
    fields => {
        username => 'username-for-room',
        password => 'password-for-room',
    }
);

We can check if the form submission was successful by asking the HTTP::Response if things went well:

  DB<7> x $mech->res->is_success;
0  1

Looking good so far. Let’s see if ping works as expected

$ ping www.heise.de
PING www.heise.de (193.99.144.85) 56(84) bytes of data.
64 bytes from www.heise.de (193.99.144.85): icmp_seq=1 ttl=247 time=20.6 ms
64 bytes from www.heise.de (193.99.144.85): icmp_seq=2 ttl=247 time=13.9 ms
^C
--- www.heise.de ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 13.941/17.281/20.621/3.340 ms

Yes! In other words: we’re in! That was easy. ☺

Putting everything together (and cleaning up the code a bit), I ended up with this:

use strict;
use warnings;

use WWW::Mechanize;

my $mech = WWW::Mechanize->new;
$mech->get('http://google.com');

# check that we have the login page and not Google or something else
# i.e. we're not logged in
if ($mech->title() =~ 'login') {
    $mech->submit_form(
        form_name => 'login',
        fields => {
            username => '<username-for-room>',
            password => '<password-for-room>'
        }
    );
    if ($mech->res->is_success) {
        print "Login successful\n";
    }
    else {
        print "Login failed\n";
    }
}
else {
    print "Already logged in\n";
}

Now I can just run the script every time I wake my laptop back up and I’m back online. Yay!

From a security perspective it’s a bit weird that the username and password are obviously tied to the room number. In other words, I could probably use the neighbouring room’s account just as easily (I guess: I couldn’t be bothered checking in the end).

The conclusion

Well, this script certainly saved me some time and hassle when waking up my laptop from the suspend state. Also, it was fun working out what pieces of the puzzle were necessary in order to build a solution. Perl saves the day7 again!

Originally posted on https://peateasea.de.


  1. Remember when finding a hotel with any wireless connectivity was a total mission? Sort of like the days when finding a power outlet at an airport to charge a laptop was really difficult and one ended up sitting on the floor next to a utility room where the cleaning staff would normally plug in a vacuum cleaner. Ah, those were the days 😉. Put another way: humanity has come a looong way. [return]
  2. I use mutt; it’s fast and one only needs to use text for email. Right? Right? [return]
  3. I also use irssi for IRC. Look, I’ve been around a while, ok? [return]
  4. I’m one of those geeks who live on the terminal, hence I tend to use a lot of terminal-based tools to get things done. [return]
  5. I don’t mean this ironically: because of the forests and the distance away from any kind of metropolis, the air is much fresher. Ever notice that the air in European cities is just awful? [return]
  6. Later, I’d tried putting my computer to sleep and then waking it up a few minutes later. The connection was still alive, so my best guess is that the timeout to keep connections alive and keep a MAC address registered is on the order of hours, but not more than two or three hours, because even such short periods of inactivity required login again. A later test showed that the timeout was after one hour. [return]
  7. Well, it saved the week really. [return]

For consistency with other DISTRIBUTION entries

Perl commits on GitHub

Published by jkeenan on Tuesday 26 March 2024 15:18

For consistency with other DISTRIBUTION entries

Use single quotes rather than double.  This will facilitate grepping
this file.

perl new_api_addr in CentOS 7 [closed]

Perl questions on StackOverflow

Published by user1309220 on Tuesday 26 March 2024 11:21

I have some code that runs on Debian 11 and I need it to run on CentOS 7. The code fails on CentOS 7 where new_api_addr is called. On CentOS 7 I get the error message:

Undefined subroutine &main::new_api_addr called at temp.pl line 94

Here are lines up to new_api_addr being called (I took out debugging lines):

use IO::File;
use HTTP::Request::Common;
use LWP::UserAgent;
use File::Copy;
use XML::Simple;
use MIME::Base64;
use Data::Dumper;
use Digest::MD5 qw(md5_hex)

# default variables
$validlogin = 0;
$logintries = 0;
$passwdagebad = 0;
$warning = 1;
$debug = 0;
$tabnum = 0;

@api_nodes = ("x.x.x.x", "x.x.x.x", "x.x.x.x");
$api_array_size = @api_nodes;
$api_index = 0;
$last_index = 0;
$api_counter = 0;
$auth_loop = 0;
$passwd_loop = 0;
$token_loop = 0;
%templatehash:

@api_nodes = ("new x.x.x.x", "new x.x.x", "new x.x.x.x");
new_api_addr();

I'm assuming new_api_addr is included in some perl module on Debian 11 that is not included on CentOS 7. How do I find out how to install the proper perl package on CentOS 7 with this routine in it?

The package Catalyst::Plugin::FormValidator missed in CPAN

r/perl

Published by /u/ruzhnikov on Tuesday 26 March 2024 10:17

Does anybody know what happened with the package Catalyst::Plugin::FormValidator, why it was removed from cpan?

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

Perl Weekly Challenge 262: Max Positive Negative

blogs.perl.org

Published by laurent_r on Tuesday 26 March 2024 03:39

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

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on March 31, 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 1: Max Positive Negative

You are given an array of integers, @ints.

Write a script to return the maximum number of either positive or negative integers in the given array.

Example 1

Input: @ints = (-3, 1, 2, -1, 3, -2, 4)
Output: 4

Count of positive integers: 4
Count of negative integers: 3
Maximum of count of positive and negative integers: 4

Example 2

Input: @ints = (-1, -2, -3, 1)
Output: 3

Count of positive integers: 1
Count of negative integers: 3
Maximum of count of positive and negative integers: 3

Example 3

Input: @ints = (1,2)
Output: 2

Count of positive integers: 2
Count of negative integers: 0
Maximum of count of positive and negative integers: 2

Although this is not clearly specified, we will consider only strictly positive and strictly negative input values (in other words, we will discard values equal to zero).

Max Positive Negative in Raku

We use Raku built-in grep, elems, and max methods to come up with a one-liner solution in Raku.

sub max-pos-neg (@in) {
    (@in.grep({$_ > 0}).elems, @in.grep({$_ < 0}).elems).max;
}

my @tests = <-3 1 2 -1 3 -2 4>, <-1 -2 -3 1>, <1 2>;
for @tests -> @test {
    printf "%-20s => ", "@test[]";
    say max-pos-neg @test;
}

This program displays the following output:

$ raku ./max-pos-neg.raku
-3 1 2 -1 3 -2 4     => 4
-1 -2 -3 1           => 3
1 2                  => 2

Max Positive Negative in Perl

This is a port to Perl of the above Raku program, with the only significant change being that we use the ternary operator (? :) to replace max.

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

sub max_pos_neg {
    my $pos_count = scalar grep {$_ > 0} @_;
    my $neg_count = scalar grep {$_ < 0} @_;
    $pos_count > $neg_count ? $pos_count : $neg_count;
}

my @tests = ( [<-3 1 2 -1 3 -2 4>], 
              [<-1 -2 -3 1>], [<1 2>] );
for my $test (@tests) {
    printf "%-20s => ", "@$test";
    say max_pos_neg @$test;
}

This program displays the following output:

$ perl ./max-pos-neg.pl
-3 1 2 -1 3 -2 4     => 4
-1 -2 -3 1           => 3
1 2                  => 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 April 7, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

5 Reasons to Sponsor the Perl Toolchain Summit

perl.com

Published on Monday 25 March 2024 18:00

Photo © Salve J. Nilsen, 2023, CC-BY-NC-4.0

TL;DR Please read and share the prospectus for the Perl Toolchain Summit.

It’s that time of year again. In a few weeks, dozens of Perl hackers will be meeting in Lisbon, Portugal to hack furiously on the Perl Toolchain. I will be there as well, working on MetaCPAN. Most of the other core MetaCPAN developers will be there as well, as is the case most years. We get lots of work done. I usually blog about it. To get an idea of what goes on, you can check out my 2023 Perl Toolchain Summit report and Salve J. Nilsen’s photos.

The summit is a great opportunity for your company to get involved and support the Perl community. Here are 5 reasons why you should sponsor the Perl Toolchain Summit.

1) Synchronous Communication

The developers who maintain CPAN and its associated tools and service are scattered all across the globe and, more importantly, in different time zones. Most of us know that it’s entirely possible to get things done at our day jobs while working remotely. It’s not always this easy when trying to co-ordinate the time, efforts and schedules of volunteers. The Perl Toolchain Summit is the only time of the year when most of these developers are in the same room together. The event gives them the luxury of synchronous, rather than asynchronous communication. Imagine walking across the room to talk to someone rather than waiting for someone who lives across an ocean to find the free time to respond to a GitHub issue or a chat message. Problems can be solved much faster when you get so many stakeholders and decision makers in the same room.

2) Face Time

We also know that communication can be hard and it doesn’t necessarily get easier when much of it happens by text. Giving the Toolchain developers the chance to work face to face means they have a greater understanding and appreciation of whom they are dealing with. The cameraderie which develops at this event allows the Toolchain developers to communicate freely and well when they’re not all together. I’m amazed at how well everyone gets along for the part of the year when we’re not in the same room. It’s a very special group of people.

3) Consensus

Some big decisions require consensus. Consensus requires getting input from many people. Being able to call a meeting to discuss topic X with all of the relevant people is kind of a big deal. Past toolchain summits have given us documents which offer a guide on how to move forward. The Lancaster Consensus is such a document.

4) Distraction-free Time

Most Open Source developers are juggling a bunch of things in their day to day lives and hacking on software is just one of those things. Many of us rarely get more than a few hours in a given week to work distraction-free on something which interests us. Sometimes we don’t even have that luxury. The Toolchain summit gives developers 3-4 days of time to keep barreling ahead on critical software. Imagine what you could do with a hobby project when all you had to worry about was getting up in the morning, having a prepared meal and then plugging in your laptop and consulting the experts sitting around you? That’s exactly what this event is like. It also has the side effect of increasing the cadence of a project in the weeks leading up to the Toolchain where everyone prepares ahead of time, in order to maximize their creativity upon arrival.

5) It Keeps the Toolchain Moving Forward

The Perl Toolchain Summit works to ensure that the parts of the Perl Ecosystem which developers (and businesses) around the world rely on, are cared for. Some problems are thorny. They require time. They require expertise. They require help and possibly a shoulder to cry on. If your business relies on Perl, then it relies on the toolchain. It relies on a healthy and secure ecosystem. These are critical things, but they’re also boring. They’re not flashy new apps. They’re not going to get you on the front page of Hacker News. They are, however, going to allow people and businesses around the world to carry on with their lives, blissfully unaware of the efforts which are going into the software which underpins some part of their existence. Sponsoring this event allows you to support the boring, important parts of Perl.

By now you’re probably thinking “shut up and take my money”. That’s wonderful! Sponsoring the event is easy. Please have a look at the prospectus. It has more information on this event and it has everything you need to get started as a sponsor. Kindly pass the prospectus along to your friends and colleagues and together we can work together to keep the Perl Toolchain moving forward.

Some app I work on needs to export some data and send it to customers in a traceable way. We need to make sure that we keep track of each filename, and also make sure that the customers can (maybe even months later) tell us which export file might need some handling. So we decided to use a rather verbose filename containing the customer name, a timestamp and the uuid of the export job eg export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8e871.zip.

Generating and sending such a mail is quite easy using eg Email::Stuffer and Email::Sender::Simple:

 my $filename = 'export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8e871.zip';
    
    my $email = Email::Stuffer
       ->to(          $customer_email )
       ->cc(          $our_archive_email )
       ->from(        $sender )
       ->subject(     "Your data" )
       ->text_body(   "Please find your data attached" )
       ->attach_file( $filename )
       ->email;
    
    Email::Sender::Simple->send( $email, { transport => $smtp } );

I tested this using a local maildev and also via google mail (as we're using that for that project..). It also worked for the customers. Well, some customers...

PEBCAK?

One customer complained that they could not open the file (on Windows). The file actually is a password "protected" zip archive containing a CSV, so I assumed they had some problems with that setup and provided some detailed instruction on how to open / extract that file and make sure that Windows does not mangle the extensions etc. The customer was satisfied. I grumbled a bit about Windows and customers and went on to do other stuff.

Some time later, due to some stupidity on my part, we sent out that file as a regular CSV file (without packing it into zip). Again, the customer complained that they could not unpack the file after downloading it and adding a zip extension. That's when I started to wonder what was really going on, because I got the mail as a plain CSV file and never should the customer need to manually add an extension.

And what going on was that the customer did not get any file extensions, just a plain string, then manually added the (in that case wrong) extension zip and only then could proceed. And the customer was not using gmail, but something else.

So I tried to open the mail in mutt, and .. the attachment was indeed mangled: The filename was truncated, the extension missing.

Headers

This prompted a closer examination of the mail headers:

Content-Type: application/octet-stream;
   name*0=export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8;
   name*1=e871.zip
   name=export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c...

Ouch!

It seems that some part of the (40 years old?) email spec cannot handle long filenames, therefore they are broken into multiple lines.

And it seems that some mail clients can handle this multi line filenames, and some cannot handle them (among them mutt, which I find sad, but in this case lucky, because I'm not sure I would ever found the real bug and just assumed customer incompetence...)

Fix it

The fix was of course easy: pack the actual file (with the still long and very verbose filename) into a zip archive with a different, much shorter name.

But it was still interesting to learn that in that case the problem was not a stupid customer or an annoying OS, but the fact the email obviously needs to printable on a dot-matrix printer and therefor should not have more than 80 characters per line...

Update: dakkar pointed out the relevant RFC 2332, Section 3.

Strawberry Perl using a separate winlibs distro

r/perl

Published by /u/Sharp_Artichoke_8237 on Monday 25 March 2024 13:26

Strawberry Perl is distributed with its own winlibs distribution. E.g., if the perl distribution is placed in c:/strawberry, the winlibs distribution is placed in c:/strawberry/c. May I replace this winlibs distribution with a different, newer winlibs distribution placed in c:/winlibs (for example)? Of course this will come with a path update.

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

Perl Weekly #661 - Perl Toolchain Summit 2024

dev.to #perl

Published by Gabor Szabo on Monday 25 March 2024 09:30

Originally published at Perl Weekly 661

Hi there!

Perl 5.39.9 was released including the new ^^ operator. It is only a development release, but I'd like to encourage you to give it a try and give feedback to the developers.

There was some nefarious activity on CPAN. Someone re-uploaded perl-5-38.2. It was reported and the security team quickly eliminated the threat.

I was wondering if I should write about the hate mails I received: one for myself as Jew (my ethnicity) triggered by what I wrote two weeks ago and one on behalf of Mohammed as a Muslim (his religion) triggered by what he wrote last week. I've removed these people from the distribution, but I think they need more accountability. I am still contemplating publishing the names of these people along with their messages so the Perl community and their employers will be aware of that. After all most of us don't want to work with abusive people, do we?

The Perl Toolchain Summit is coming again and they need your help sponsoring the even. Here is the Sponsor prospectus for Perl Toolchain Summit 2024. Last year I ran an online course about Open Source development and the proceedings went to the summit (though I transferred them late, so probably they could not use that in time). This year I don't have the time for that, but I hope you will see the value in the summit and will sponsor it directly.

Enjoy your week!

--
Your editor: Gabor Szabo.

Announcements

perl 5.39.9 released

With the new ^^ logical xor operator. And a reminder: it is a development release.

Articles

Changes in MooX::Role::Parameterized

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.

Security team

perl-5.38.2 suspiciously reposted to CPAN?

Perl

This week in PSC (141) | 2024-03-21

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 - 262

Welcome to a new week with a couple of fun tasks "Max Positive Negative" and "Count Equal Divisible". 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 - 261

Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Element Digit Sum" and "Multiply by Two" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.

These Elements, They’re Multiplying!

Using pack() then unpack() to get the element sum. This is something very handy. Find out more in the post.

Two Elements

Lots of Raku magic, '>>.comb' and '>>.sum' can be lethal. Keep it up great work.

Can You Digit It?

Using CPAN module makes it compact and elegant. Did you know that 261 is an Odious Number? Well done.

Perl Weekly Challenge: Week 261

This week task was ideal for Raku one-liner and here we have one, incredible.

Bits, Digits and Numbers

Pure mathematical approach with the help of CPAN module. Don't you love the one-liner it generates? Really cool.

Perl Weekly Challenge 261: Element Digit Sum

Comparative solutions in Perl and Raku can be fun. Plenty to learn just following the code.

Perl Weekly Challenge 261: Multiply by Two

Using Bag in Raku is an ideal choice, something any Perl dev can relate to. Thanks for sharing.

a short one!

Being master of Raku one-liner, we have yet another cute one-liner, you don't want to skip it.

Perl Weekly Challenge 261

Master of Perl one-liner is at his best. You don't want to miss it. Highly recommended.

Summing Up Two Short Challenge Elements

Simple yet elegant solutions in Perl. Task analysis is not to be missed though.

Two Elements, Multiplied by Digit Sum

Clever use of Raku's Reduction Metaoperator makes it ideal to get the job done. CPAN has an alternative to the Raku's counterpart. Well done.

Digits and doubling

Lack of clarity in task description handled very well. Task analysis is always fun to read.

The Weekly Challenge #261

CPAN module can make your life fun and easy. You must checkout the solutions.

Two Elements Who Adore You

You will love how Set of Raku can be fit for the job. Thanks for sharing knowledge with us.

Weekly Challenge 261

Near identical solutions in Perl and Python. No wonder Python is second choice for all Perl programmer.

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.

perldelta for a2b66c25985f, save PL_comppad safely

Perl commits on GitHub

Published by tonycoz on Sunday 24 March 2024 22:25

perldelta for a2b66c25985f, save PL_comppad safely

prepare_export_lexical: save PL_comppad safely

Perl commits on GitHub

Published by tonycoz on Sunday 24 March 2024 22:11

prepare_export_lexical: save PL_comppad safely

When the pad being saved and the pad for PL_compcv is the same,
in some cases the actual exports would result in reallocating the
AvARRAY() for the saved PL_comppad.

The LEAVE in finish_export_lexical() would restore the old PL_comppad
(which is fine) and the pre-reallocation PL_curpad (which isn't fine).

This would later panic.

SAVECOMPPAD; restores PL_comppad on LEAVE and then restores PL_curpad
from PL_comppad, preventing the desync between those values.

It's unclear to me why only the save_BEGINs; causes this, but the fix
does fix a real problem and prevents the panics that I'm aware of
here.

Fixes #21981

Revert "testsuite.yml: fix ASAN build tests"

Perl commits on GitHub

Published by tonycoz on Sunday 24 March 2024 22:08

Revert "testsuite.yml: fix ASAN build tests"

This reverts commit d1971b5f57c5a31b1d61d7b2e5816942d69ed954.

ctions/runner-images#9491 has been fixed.

(cdlxxxviii) 12 great CPAN modules released last week

r/perl

Published by /u/niceperl on Sunday 24 March 2024 14:59

(cdlxxxviii) 12 great CPAN modules released last week

Niceperl

Published by Unknown on Sunday 24 March 2024 15:59

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::Netdisco - An open source web-based network management tool.
    • Version: 2.074001 on 2024-03-19, with 16 votes
    • Previous CPAN version: 2.073001 was 6 days before
    • Author: OLIVER
  2. Catalyst::Manual - The Catalyst developer's manual
    • Version: 5.9013 on 2024-03-22, with 49 votes
    • Previous CPAN version: 5.9012 was 1 month, 19 days before
    • Author: ETHER
  3. CGI - Handle Common Gateway Interface requests and responses
    • Version: 4.64 on 2024-03-18, with 43 votes
    • Previous CPAN version: 4.63 was 12 days before
    • Author: LEEJO
  4. CPAN::Audit - Audit CPAN distributions for known vulnerabilities
    • Version: 20240318.001 on 2024-03-19, with 13 votes
    • Previous CPAN version: 20240307.001 was 10 days before
    • Author: BDFOY
  5. Data::UUID - Globally/Universally Unique Identifiers (GUIDs/UUIDs)
    • Version: 1.227 on 2024-03-18, with 32 votes
    • Previous CPAN version: 1.226 was 3 years, 11 months, 6 days before
    • Author: GTERMARS
  6. DBD::mysql - A MySQL driver for the Perl5 Database Interface (DBI)
    • Version: 5.004 on 2024-03-19, with 55 votes
    • Previous CPAN version: 5.003 was 3 months, 18 days before
    • Author: DVEEDEN
  7. Minion - Job queue
    • Version: 10.29 on 2024-03-19, with 106 votes
    • Previous CPAN version: 10.28 was 3 months, 21 days before
    • Author: SRI
  8. Module::CoreList - what modules shipped with versions of perl
    • Version: 5.20240320 on 2024-03-20, with 43 votes
    • Previous CPAN version: 5.20240223 was 26 days before
    • Author: BINGOS
  9. Pod::Weaver - weave together a Pod document from an outline
    • Version: 4.020 on 2024-03-21, with 34 votes
    • Previous CPAN version: 4.019 was 1 year, 2 months, 9 days before
    • Author: RJBS
  10. Spreadsheet::ParseXLSX - parse XLSX files
    • Version: 0.35 on 2024-03-19, with 19 votes
    • Previous CPAN version: 0.34 was 6 days before
    • Author: NUDDLEGG
  11. SPVM - SPVM Language
    • Version: 0.989092 on 2024-03-23, with 31 votes
    • Previous CPAN version: 0.989087 was 8 days before
    • Author: KIMOTO
  12. Variable::Magic - Associate user-defined magic to variables from Perl.
    • Version: 0.64 on 2024-03-18, with 24 votes
    • Previous CPAN version: 0.63 was 1 year, 5 months, 28 days before
    • Author: VPIT

Weekly Challenge 261

dev.to #perl

Published by Simon Green on Sunday 24 March 2024 06:32

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: Element Digit Sum

Task

You are given an array of integers, @ints.

Write a script to evaluate the absolute difference between element and digit sum of the given array.

My solution

Given that Perl doesn't care (most of the time) between numbers and strings, this is one of those challenges that is easier to do in Perl.

my $element_sum = sum(@ints);
my $digit_sum   = sum( map { split // } @ints );
say abs( $element_sum - $digit_sum );

The sum function comes from List::Util. The first line gets the sum of the elements. The second line splits the integers by the digits and calculates the sum. The final line calculates and display the absolute difference.

My Python solution is as follows

def element_digit_sum(ints: list) -> int:
    element_sum = sum(ints)
    digit_sum = sum(int(i) for s in map(str, ints) for i in s)
    return abs(element_sum - digit_sum)

It follows the same logic and the Perl code. The second line does the following

  • map(str, ints) turns the list of integers into a generator of strings
  • for s in iterates over the generator
  • for i in s iterates over each character in the string
  • int(i) turns that character into an integer
  • sum() turns the list of integers into a sum of the values

Examples

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

$ ./ch-1.py 1 12 3
9

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

$ ./ch-1.py 236 416 336 350
1296

Task 2: Multiply by Two

Task

You are given an array of integers, @ints and an integer $start..

Write a script to do the following:

  1. Look for $start in the array @ints, if found multiply the number by 2
  2. If not found stop the process otherwise repeat

In the end return the final value.

My solution

This seems relatively straight forward. I keep multiplying the start by two until the value does not appear in the list. For performance, I could have converted the list into a set (hash in Perl), as checking in-ness (is that a word?) is faster that way. However, we are dealing with a small list, so it is not required.

def multiple_by_two(ints: list, start: int) -> int:
    solution = start
    while solution in ints:
        solution *= 2

    return solution

Examples

$ ./ch-2.py 5 3 6 1 12 3
24

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

$ ./ch-2.py 5 6 7 2
2

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 7.

Part 1: Element Digit Sum

You are given an array of integers, @integers. Write a script to evaluate the absolute difference between every element and the digit sum of the entire given array.

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

"ch-1.pl" 1


preamble 2
element digit sum 5
main 6

For this problem we do not need to include very much. We’re just specifying to use the current version of Perl, for all the latest features in the language. This fragment is also used in Part 2.

preamble 2 ⟩≡


use v5.38;

Fragment referenced in 1, 7.

First, let’s consider how we compute the digit sum for an array of integers. If we we make sure that all multi-digit numbers are expanded into lists of digits then this is the sum of the concatenation of all such lists, along with single digit numbers.

The expansion of multi-digit numbers is handled by map, and the sum is taken with unpack and the resulting final array. A key thing to remember here is that Perl will flatten all lists inside the array so all the results from the map will be in a list of single digits.

compute digit sum 3 ⟩≡


my $digit_sum = unpack(q/%32I*/, pack(
q/I*/, map {split //, $_} @{$integers})
);

Fragment referenced in 5.

Defines: $digit_sum 5.

Uses: $integers 5.

The element sum is the same procedure as the digit sum, but just without the map.

compute element sum 4 ⟩≡


my $element_sum = unpack(q/%32I*/, pack q/I*/, @{$integers});

Fragment referenced in 5.

Defines: $element_sum 5.

Uses: $integers 5.

element digit sum 5 ⟩≡


sub element_digit_sum{
my($integers) = [@_];
compute digit sum 3
compute element sum 4
return abs($element_sum - $digit_sum)
}

Fragment referenced in 1.

Defines: $integers 3, 4.

Uses: $digit_sum 3, $element_sum 4.

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

main 6 ⟩≡


MAIN:{
say element_digit_sum 1, 2, 3, 45;
say element_digit_sum 1, 12, 3;
say element_digit_sum 1, 2, 3, 4;
say element_digit_sum 236, 416, 336, 350;
}

Fragment referenced in 1.

Sample Run
$ perl perl/ch-1.pl 
36 
9 
0 
1296
    

Part 2: Multiply by Two

You are given an array of integers, @integers and an integer $start. Write a script to do the following:

a) Look for $start in the array @integers, if found multiply the number by 2.

b) If not found stop the process, otherwise repeat.

In the end return the final value.

We’ll contain the solution in a single recursive function. The completed solution will just have that function plus a few tests.

"ch-2.pl" 7


preamble 2
search and multiply 8
main 9

This is our principal function. As can be seen, it’s very short! The logic here is simple: for each recursive call check for $start in the array and, if found, double $start and keep recursing. Otherwise, return $start.

search and multiply 8 ⟩≡


sub search_multiply{
my($start) = shift;
return $start if 0 == grep {$start == $_} @_;
search_multiply($start + $start, @_);
}

Fragment referenced in 7.

Finally, here’s a few tests to confirm everything is working right.

main 9 ⟩≡


MAIN:{
say search_multiply 3, 5, 3, 6, 1, 12;
say search_multiply 1, 1, 2, 3, 4;
say search_multiply 2, 5, 6, 7;
}

Fragment referenced in 7.

Sample Run
$ perl ch-2.pl 
24 
8 
2
    

References

The Weekly Challenge 261
Generated Code

This week in PSC (141) | 2024-03-21

blogs.perl.org

Published by Perl Steering Council on Thursday 21 March 2024 23:01

This week, we:

  • Talked about some ideas for discussion at the upcoming PTS
  • Discussed the current blocked state of bleadperl following the 5.39.9 release and how to unblock it
  • Finished reviewing the release blocker bugs
  • Discussed how MetaCPAN should better handle perl releases and permissions

Perl Weekly Challenge 261: Multiply by Two

blogs.perl.org

Published by laurent_r on Thursday 21 March 2024 19:41

These are some answers to the Week 261, 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 24, 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: Multiply by Two

You are given an array of integers, @ints and an integer $start.

Write a script to do the following:

a) Look for $start in the array @ints, if found multiply the number by 2

b) If not found stop the process otherwise repeat

In the end return the final value.

Example 1

Input: @ints = (5,3,6,1,12) and $start = 3
Output: 24

Step 1: 3 is in the array so 3 x 2 = 6
Step 2: 6 is in the array so 6 x 2 = 12
Step 3: 12 is in the array so 12 x 2 = 24

24 is not found in the array so return 24.

Example 2

Input: @ints = (1,2,4,3) and $start = 1
Output: 8

Step 1: 1 is in the array so 1 x 2 = 2
Step 2: 2 is in the array so 2 x 2 = 4
Step 3: 4 is in the array so 4 x 2 = 8

8 is not found in the array so return 8.

Example 3

Input: @ints = (5,6,7) and $start = 2
Output: 2

2 is not found in the array so return 2.

First, let's note that if $start is equal to 0 and if 0 is also found in the input array of integers, we will enter in an endless loop. We will add a condition to avoid that from happening.

Multiply by Two in Raku

In Raku, we will start by storing the input array of integers into a Bag, i.e. a collection of distinct objects with integer weights, to enable fast lookup. We could also have used a Set instead of a bag, since we don't really need integer weights, but a Bag is what came to my mind first. Then, we simply multiply $start by two until it is no longer found in the Bag.

sub multiply-by-two ($start is copy where * != 0, @in) {
    my $bag = @in.Bag;
    $start *= 2 while $bag{$start};
    return $start;
}

my @tests = (3, (5,3,6,1,12)), (1, (1,2,4,3)), (2, (5,6,7));
for @tests -> @test {
    printf "%d - %-15s => ", @test[0], "@test[1]";
    say multiply-by-two @test[0], @test[1];
}

This program displays the following output:

$ raku ./multiply-by-two.raku
3 - 5 3 6 1 12      => 24
1 - 1 2 4 3         => 8
2 - 5 6 7           => 2

Multiply by Two in Perl

This is a port to Perl of the above Raku program. Perl doesn't have Bags, but we can use a hash to the same effect.

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

sub multiply_by_two {
    my $start = shift;
    die "$start cannot be 0" if $start == 0;
    my %present = map { $_ => 1 } @_;
    $start *= 2 while $present{$start};
    return $start;
}

my @tests = ( [3, [5,3,6,1,12]], [1, [1,2,4,3]], [2, [5,6,7]] );
for my $test (@tests) {
    printf "%d - %-15s => ", $test->[0], "@{$test->[1]}";
    say multiply_by_two @$test[0], @{$test->[1]};
}

This program displays the following output:

$ raku ./multiply-by-two.raku
3 - 5 3 6 1 12      => 24
1 - 1 2 4 3         => 8
2 - 5 6 7           => 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 31, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Hotel hotspot hijinks

r/perl

Published by /u/oalders on Thursday 21 March 2024 16:45

Changes in MooX::Role::Parameterized

blogs.perl.org

Published by E. Choroba on Thursday 21 March 2024 08:36

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 0.501;

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 0.501;

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

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

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.

(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

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

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

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. ```

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

(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.

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
    

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