Published by Amber Krawczyk on Saturday 01 June 2024 21:26
Is there a way to replace accented characters by their plain version, something like
tr/ûšḥ/ush/?
Published by Timothy R. Butler on Saturday 01 June 2024 05:38
I'm trying to implement Google's YouTube video uploading API in Perl, which, alas has no library for such. I've run into an issue with the actual PUT
to upload the video file. LWP::UserAgent
has a very helpful function to avoid having to stream the upload of a large file by simply referencing the file's name in an arrayref like so:
my $ua = LWP::UserAgent->new;
my $upload_url = "https://myapi";
my $localPath = "myBigVideoFile.mp4";
my $upload_response = $ua->put( $upload_url, 'Content_Type' => 'form-data', 'Content' => [ 'file' => [ $localPath ] ] );
However, that isn't the format Google's API expects. It wants the Content-Type to be 'video/*' and it wants the entire body of the response to be the file, not have it tucked away as the "file" field in a form. But changing the code to match Google's expectations disables LWP's handy file loading function. For example:
my $upload_response = $ua->put( $upload_url, 'Content_Type' => 'video/*', 'Content' => [ $localPath ] );
In that case, the LWP request object shows just the file name as the content, rather than streaming out the content.
Is there any way to activate LWP's file loading magic, or easily simulate it, so that I can achieve Google's required format without preloading the entire file (obviously not a good idea!).
Here's Google needed HTTP format:
PUT API_ADDRESS_GOES_HERE HTTP/1.1
Authorization: Bearer AUTH_TOKEN_GOES_HERE
Content-Length: CONTENT_LENGTH_GOES_HERE
Content-Type: video/*
BINARY_FILE_DATA
(In the actual code, I'm using LWP::Authen::OAuth2
on top of LWP::UserAgent
, but everything I outlined above happens when I send the data to my own endpoint using just UserAgent.
Published by /u/perlancar on Saturday 01 June 2024 01:39
submitted by /u/perlancar [link] [comments] |
Published by perlancar on Saturday 01 June 2024 01:37
dist | author | abstract | date |
---|---|---|---|
Alien-NLopt | DJERIUS | Build and Install the NLopt library | 2024-05-01T05:00:12 |
Alien-cue | PLICEASE | Find or download the cue configuration language tool | 2024-05-07T11:34:32 |
Alien-libversion | GDT | Alien wrapper for libversion | 2024-05-01T20:53:07 |
Alien-poetry | OLIVER | Download and install poetry | 2024-05-11T11:33:08 |
Amon2-Plugin-Web-Flash | YOSHIMASA | Ruby on Rails flash for Amon2 | 2024-05-26T03:25:23 |
App-Codit | HANJE | IDE for and in Perl | 2024-05-20T08:51:39 |
App-NutrientUtils | PERLANCAR | Utilities related to nutrients | 2024-05-26T00:06:02 |
App-htidx | GBROWN | generate static HTML directory listings. | 2024-05-29T11:03:56 |
App-rdapper | GBROWN | a simple console-based RDAP client. | 2024-05-29T23:00:49 |
Archive-SCS | NAUTOFON | SCS archive controller | 2024-05-21T18:27:52 |
Authorization-AccessControl | TYRRMINAL | Hybrid RBAC/ABAC access control | 2024-05-16T03:53:26 |
Bencher-ScenarioBundle-Accessors | PERLANCAR | Scenarios to benchmark class accessors | 2024-05-13T00:05:21 |
Bencher-ScenarioBundle-Algorithm-Diff | PERLANCAR | Scenarios to benchmark Algorithm::Diff | 2024-05-11T00:06:17 |
Bencher-ScenarioBundle-Graphics-ColorNames | PERLANCAR | Scenarios to benchmark Graphics::ColorNames and related modules | 2024-05-12T00:05:13 |
Bencher-ScenarioBundle-Log-Any | PERLANCAR | Scenarios for benchmarking Log::Any | 2024-05-20T00:06:19 |
Bencher-ScenarioBundle-Log-ger | PERLANCAR | Scenarios for benchmarking Log::ger | 2024-05-21T00:05:46 |
Complete-Nutrient | PERLANCAR | Completion routines related to nutrients | 2024-05-31T00:05:25 |
Couch-DB | MARKOV | thick CouchDB interface | 2024-05-29T16:37:08 |
Data-HTML-Footer | SKIM | Data object for HTML footer. | 2024-05-31T09:32:54 |
Data-Message-Board | SKIM | Data objects for message board. | 2024-05-27T18:30:24 |
Data-Person | SKIM | Data objects for person. | 2024-05-27T08:46:48 |
Dist-Zilla-Plugin-Sorter | PERLANCAR | Plugin to use when building Sorter::* distribution | 2024-05-07T00:05:19 |
Dist-Zilla-Stash-OnePasswordLogin | RJBS | get login credentials from 1Password | 2024-05-25T16:30:09 |
Feed-Data-AlJazeera | LNATION | The great new Feed::Data::AlJazeera! | 2024-05-09T05:50:01 |
Feed-Data-BBC | LNATION | Waiting for comedians to present the news | 2024-05-02T08:38:34 |
Feed-Data-CNN | LNATION | The rest of the world will follow. | 2024-05-02T10:11:29 |
FreeDesktop-Icons | HANJE | Use icon libraries quick & easy | 2024-05-31T17:26:09 |
Game-Cribbage | LNATION | The great new Game::Cribbage! | 2024-05-15T00:15:17 |
Graphics-ColorNamesCMYK | PERLANCAR | Define CMYK values for common color names | 2024-05-10T00:05:12 |
Graphics-ColorNamesCMYK-BannersCom | PERLANCAR | Basic CMYK colors from banners.com | 2024-05-17T00:05:09 |
Graphics-ColorNamesCMYK-JohnDecemberCom | PERLANCAR | CMYK color names from johndecember.com | 2024-05-19T00:05:21 |
Graphics-ColorNamesCMYK-Pantone | PERLANCAR | Pantone colors | 2024-05-14T00:05:54 |
Graphics-ColorNamesCMYK-ToutesLesCouleursCom | PERLANCAR | CMYK colors from http://toutes-les-couleurs.com/ (red) | 2024-05-16T00:06:24 |
Graphics-ColorNamesLite | PERLANCAR | Define RGB values for common color names (lite version) | 2024-05-09T00:05:39 |
Hades-Realm-Rope | LNATION | Hades realm for Moose | 2024-05-20T13:39:42 |
HashData-Color-CMYK-JohnDecemberCom | PERLANCAR | CMYK color names (from johndecember.com) | 2024-05-18T00:05:57 |
HashData-Color-CMYK-ToutesLesCouleursCom | PERLANCAR | CMYK color names (from ToutesLesCouleursCom) | 2024-05-15T00:06:01 |
HashData-Color-PantoneToCMYK | PERLANCAR | Mapping of Pantone color names to CMYK values | 2024-05-08T00:05:41 |
HashData-ColorCode-CMYK-JohnDecemberCom | PERLANCAR | CMYK color names (from johndecember.com) | 2024-05-22T00:06:06 |
HashData-ColorCode-CMYK-Pantone | PERLANCAR | Mapping of Pantone color names to CMYK values | 2024-05-23T00:05:32 |
HashData-ColorCode-CMYK-ToutesLesCouleursCom | PERLANCAR | CMYK color names (from ToutesLesCouleursCom) | 2024-05-24T00:06:00 |
Linux-Landlock | MBALLARIN | An interface to the Landlock sandboxing facility of Linux | 2024-05-09T20:12:52 |
Locale-Unicode | JDEGUEST | Unicode Locale Identifier compliant with BCP47 and CLDR | 2024-05-17T08:05:23 |
Log-Log4perl-Config-YamlConfigurator | SVW | Reads Log4perl YAML configurations | 2024-05-29T07:51:19 |
Math-NLopt | DJERIUS | Math::NLopt – Perl interface to the NLopt optimization library | 2024-05-01T07:53:48 |
Mojolicious-Plugin-Authorization-AccessControl | TYRRMINAL | Integrate Authorization::AccessControl into Mojolicious | 2024-05-16T23:23:55 |
Mojolicious-Plugin-Config-Structured-Bootstrap | TYRRMINAL | Autoconfigure Mojolicious application and plugins | 2024-05-20T13:39:53 |
Mojolicious-Plugin-Data-Transfigure | TYRRMINAL | Mojolicious adapter for Data::Transfigure | 2024-05-18T03:42:37 |
Net-EPP-MITMProxy | GBROWN | A generic EPP proxy server framework. | 2024-05-02T11:56:41 |
Ogma | LNATION | Command Line Applications via Rope | 2024-05-07T08:27:11 |
OpenSearch | LHRST | It's new $module | 2024-05-15T15:22:31 |
Password-OnePassword-OPCLI | RJBS | get items out of 1Password with the "op" CLI | 2024-05-25T15:24:06 |
PerlIO-win32console | TONYC | Win32 console output layer | 2024-05-26T13:03:53 |
Plack-Middleware-Zstandard | PLICEASE | Compress response body with Zstandard | 2024-05-10T18:08:23 |
QRCode-Any | PERLANCAR | Common interface to QRCode functions | 2024-05-06T00:06:19 |
RT-Extension-Import-CSV | BPS | RT-Extension-Import-CSV Extension | 2024-05-15T18:16:51 |
Sah-SchemaBundle-Business-ID-NIK | PERLANCAR | Sah schemas related to Indonesian citizenship registration numbers (NIK) | 2024-05-01T00:05:13 |
Sah-SchemaBundle-Business-ID-NKK | PERLANCAR | Sah schemas related to Indonesian family card number (NKK) | 2024-05-02T00:05:52 |
Sah-SchemaBundle-Business-ID-NOPPBB | PERLANCAR | Sah schemas related to Indonesian property tax numbers (NOP PBB) | 2024-05-03T00:05:32 |
Sah-SchemaBundle-Business-ID-NPWP | PERLANCAR | Sah schemas related to Indonesian taxpayer registration number (NPWP) | 2024-05-04T00:05:59 |
Sah-SchemaBundle-Business-ID-SIM | PERLANCAR | Sah schemas related to Indonesian driving license number (nomor SIM) | 2024-05-05T00:06:14 |
Salus | LNATION | The great new Salus! | 2024-05-09T20:06:13 |
SortKey-Num-similarity_jaccard | PERLANCAR | Jaccard coefficient of a string to a reference string, as sort key | 2024-05-30T00:05:29 |
Super-Powers | LNATION | The hiddden truth | 2024-05-02T04:21:41 |
TableData-Business-ID-BPOM-NutritionLabelRef | PERLANCAR | Nutrients | 2024-05-27T00:05:19 |
TableData-Health-Nutrient | PERLANCAR | Nutrients | 2024-05-25T00:05:57 |
TableDataRole-Source-DBI | PERLANCAR | Role to access table data from DBI | 2024-05-28T00:05:38 |
TableDataRole-Source-SQLite | PERLANCAR | Role to access table data from SQLite database table/query | 2024-05-29T00:05:31 |
Tags-HTML-DefinitionList | SKIM | Tags helper for definition list. | 2024-05-17T16:54:28 |
Tags-HTML-Navigation-Grid | SKIM | Tags helper for navigation grid. | 2024-05-10T18:53:42 |
Tags-HTML-Tree | SKIM | Tags helper for Tree. | 2024-05-01T16:50:02 |
Tk-DynaMouseWheelBind | HANJE | Wheel scroll panes filled with widgets | 2024-05-20T18:53:11 |
URI-Shorten | TEODESIAN | Shorten URIs so that you don't have to rely on external services | 2024-05-07T08:50:48 |
URI-Shortener | TEODESIAN | Shorten URIs so that you don't have to rely on external services | 2024-05-07T15:53:48 |
Version-libversion-XS | GDT | Perl binding for libversion | 2024-05-01T20:09:03 |
XDR-Parse | EHUELS | Parse XDR (eXternal Data Representation) definitions into an AST (Abstract Syntax Tree) | 2024-05-17T13:01:54 |
e | TIMKA | The great new e! | 2024-05-08T15:09:45 |
optional | EXODIST | Pragma to optionally load a module (or pick from a list of modules) and provide a constant and some tools for taking action depending on if it loaded or not. | 2024-05-14T21:33:17 |
perl-libssh | QGARNIER | Support for the SSH protocol via libssh. | 2024-05-28T08:35:27 |
Number of new CPAN distributions this period: 79
Number of authors releasing new CPAN distributions this period: 25
Authors by number of new CPAN distributions this period:
No | Author | Distributions |
---|---|---|
1 | PERLANCAR | 31 |
2 | LNATION | 8 |
3 | SKIM | 6 |
4 | TYRRMINAL | 4 |
5 | HANJE | 3 |
6 | GBROWN | 3 |
7 | TEODESIAN | 2 |
8 | DJERIUS | 2 |
9 | RJBS | 2 |
10 | PLICEASE | 2 |
11 | GDT | 2 |
12 | BPS | 1 |
13 | YOSHIMASA | 1 |
14 | NAUTOFON | 1 |
15 | OLIVER | 1 |
16 | MARKOV | 1 |
17 | TONYC | 1 |
18 | LHRST | 1 |
19 | MBALLARIN | 1 |
20 | TIMKA | 1 |
21 | SVW | 1 |
22 | EXODIST | 1 |
23 | QGARNIER | 1 |
24 | JDEGUEST | 1 |
25 | EHUELS | 1 |
Published by Anonymous on Saturday 01 June 2024 00:01
I just started learning Perl. I attempted to make a simple calculator that takes input from the command line. Input: 5 * 10
. Output: 50
. But instead, it just prints 5. Here's the code:
#!usr/bin/perl
use strict;
use warnings;
my $op = $ARGV[1];
my $outpt = eval("return $ARGV[0]"."$op"."$ARGV[2]");
print "$outpt"."\n";
Any advice would be appreciated.
I tried to input all as one string instead, but that resulted in terminal output no matches found. How should I fix the error.
Published by /u/saiftynet on Friday 31 May 2024 20:16
submitted by /u/saiftynet [link] [comments] |
Is it possible to display an image to the user, without loading all the trappings of a whole widget / event-loop environment like Prima, Tk, Wx, Win32::GUI, etc?
Specifically, I want something simple that I can execute in a BEGIN block to display a splash image to the user while the rest of the application is compiled and initializes, which takes about 5-10 seconds. The program in question is a perl Wx application running under MS Windows.
Published by user15382501 on Friday 31 May 2024 19:48
I am trying to use unpack logic of perl in unix and Linux, But see it sa huge diffrence when I iterate all the input binary string , Not sure how to solve the issue ??? or is platform related ???
$binaryString = "\x00\x00\x00\x00";
so my code in Unix
$intval = unpack("i*", $binaryString);
This returns 0 as expected.
When I run the same in Linux, it gives a large value. In order to fix this issue I read only the last bytes
unpack("i*", substr($binaryString,3,1))
This returns 0 as expected.
But if the Binary String contains the value
$binaryString = "\x00\x00\x89\x9d";
Unix return 35229 but Linux its return only 157 as I am reading the last character...But I want the same value 35229 in Linux
Published by Jason M on Friday 31 May 2024 17:22
I have a bunch of old perl scripts that use SSH::Expect. When they get to the $ssh->login() stage they occasionally appear to fail on the password prompt. It will indicate a login failed and prompt for password again.
I havent been able to figure out why this started happening, but am wondering if there's a workaround. I'm not able to change to a different SSH model (like openssh etc) at this time due to the large # that use SSH::Expect.
If it is sending the first password attempt too quickly, is there a way to make sure it waits for the full prompt to appear?
If that 2nd password prompt appears, is there a way to get it to send the password again?
this is the relevant code:
my $ssh = Net::SSH::Expect->new (
host => $deviceIpAddr,
timeout => 3,
log_stdout => 1,
password=> $passwd,
user => $username,
ssh_option => '-o UserKnownHostsFile=/dev/null',
);
$login_output = $ssh->login();
Published by iabyn on Friday 31 May 2024 09:34
perldelta: fix 'perlguts for PERL_RC_STACK' entry The original entry was copied from 5.39.something's perldelta, and just mentioned some more rpp_ functions being added to perlguts. But *all* rpp_ function are new to 5.40.0, not just those extra ones. So make the entry in perldelta more generic.
Published by PPP on Friday 31 May 2024 08:23
I have a file (file.txt). Data gets appended on it every minute. Now, the fie size is getting higher and higher. What I want is that whenever the file size crosses 800MB size, all the lines from the top gets deleted. How can this be done in perl?
Published by haarg on Friday 31 May 2024 05:40
document use importing builtin version bundles in perldelta
Published by haarg on Friday 31 May 2024 05:40
document builtin module as stable in perldelta
Published by haarg on Friday 31 May 2024 05:40
document try/catch and multi-var for as stable in perldelta
Published by haarg on Friday 31 May 2024 05:40
normalize indentation in perldelta
I am making a script with multiple threads, and one of the threads I wish to make is a "cpu usage monitoring thread" that checks both "overall" cpu usage and the "current script cpu usage" or external PID cpu usage.
Then I can decide if any of my threads need to sleep for the moment while CPU is recovering from something (like maybe its executing something heavy) then my perl script needs to adjust.
I wish it will also be EFFICIENT and ACCURATE as much as possible. I don't want the perl script have high CPU usage "IF" there are apps still doing some heavy jobs. Cross Platform would be nice, but if a Windows Solution is more efficient. Please share.
For now I can't find any good solution. :(
So I need:
Here, there is a subroutine named thread_proc_monitor inefficiently just check for the overall CPU usage
# https://perldoc.perl.org/threads::shared use strict; use warnings; use threads; use threads::shared; use Time::HiRes qw(time); # Multi-Threaded Sync of 3 functions: Output should be in order 1 -> 2 -> 3 # Shared global variable our $global_counter :shared = 0; our $max_global_counter :shared = 50000; our $global_lock :shared = "UNLOCKED"; our $global_order :shared = 1; our $global_prev_order :shared = $global_order +1; our $cpu_usage :shared = 0; our $sleep_time :shared = 0; # Thread subroutine sub thread_function { my $subroutine_name = (caller(0))[3]; my $order = shift; while($global_counter < $max_global_counter) { thread_termination(); if ($global_lock eq "UNLOCKED" && $global_order == $order) { $global_lock = "LOCKED"; $global_counter++; if ($global_order != $global_prev_order) { print "GOOD-> CUR:$global_order PREV:$global_prev_order "; } else { die; } print "Thread $order ", threads->self->tid, ": Global counter = $global_counter\n"; if ($global_order > 2){ $global_order = 1; } else { $global_prev_order = $global_order; $global_order++; } # Keep looping # if ($global_counter > 900) { $global_counter = 0;} $global_lock = "UNLOCKED"; } my $actual_sleep_time = $sleep_time; my $start_time = time(); # sleep $global_counter; sleep $sleep_time; my $end_time = time(); my $duration = $end_time - $start_time; # print "sleep:[$actual_sleep_time] $duration seconds has passed...\n"; } $global_lock = "RELEASED"; } sub thread_proc_monitor { # Monitor overall CPU process usage, adjust accordingly while(){ thread_termination(); $cpu_usage = `wmic cpu get loadpercentage /format:value`; $cpu_usage =~ s/\n//g; (my $na, $cpu_usage) = split '=', $cpu_usage; sleep 1; } } sub thread_sleep_time { while(){ thread_termination(); if ($cpu_usage < 10){ $sleep_time = 0.0; } elsif ($cpu_usage < 20){ $sleep_time = 0.5; } elsif ($cpu_usage < 30){ $sleep_time = 1.0; } elsif ($cpu_usage < 40){ $sleep_time = 2.5; } elsif ($cpu_usage < 50){ $sleep_time = 4; } else { $sleep_time = 5; } if ($cpu_usage >= 20){ print "Slowing down by ".$sleep_time." seconds...\n"; } sleep(1); } } sub thread_termination { if ($global_lock eq "RELEASED"){ threads->exit(0); } } # Create three threads my $thread1 = threads->create(\&thread_function, 1); my $thread2 = threads->create(\&thread_function, 2); my $thread3 = threads->create(\&thread_function, 3); my $thread4 = threads->create(\&thread_proc_monitor, 4); my $thread5 = threads->create(\&thread_sleep_time, 5); # Wait for the threads to complete $thread1->join(); $thread2->join(); $thread3->join(); $thread4->join(); $thread5->join(); # other notes: # threads->exit(); # my $errno :shared = dualvar($!,$!); # https://perldoc.perl.org/threads::shared use strict; use warnings; use threads; use threads::shared; use Time::HiRes qw(time); # Multi-Threaded Sync of 3 functions: Output should be in order 1 -> 2 -> 3 # Shared global variable our $global_counter :shared = 0; our $max_global_counter :shared = 50000; our $global_lock :shared = "UNLOCKED"; our $global_order :shared = 1; our $global_prev_order :shared = $global_order +1; our $cpu_usage :shared = 0; our $sleep_time :shared = 0; # Thread subroutine sub thread_function { my $subroutine_name = (caller(0))[3]; my $order = shift; while($global_counter < $max_global_counter) { thread_termination(); if ($global_lock eq "UNLOCKED" && $global_order == $order) { $global_lock = "LOCKED"; $global_counter++; if ($global_order != $global_prev_order) { print "GOOD-> CUR:$global_order PREV:$global_prev_order "; } else { die; } print "Thread $order ", threads->self->tid, ": Global counter = $global_counter\n"; if ($global_order > 2){ $global_order = 1; } else { $global_prev_order = $global_order; $global_order++; } # Keep looping # if ($global_counter > 900) { $global_counter = 0;} $global_lock = "UNLOCKED"; } my $actual_sleep_time = $sleep_time; my $start_time = time(); # sleep $global_counter; sleep $sleep_time; my $end_time = time(); my $duration = $end_time - $start_time; # print "sleep:[$actual_sleep_time] $duration seconds has passed...\n"; } $global_lock = "RELEASED"; } sub thread_proc_monitor { # Monitor overall CPU process usage, adjust accordingly while(){ thread_termination(); $cpu_usage = `wmic cpu get loadpercentage /format:value`; $cpu_usage =~ s/\n//g; (my $na, $cpu_usage) = split '=', $cpu_usage; sleep 1; } } sub thread_sleep_time { while(){ thread_termination(); if ($cpu_usage < 10){ $sleep_time = 0.0; } elsif ($cpu_usage < 20){ $sleep_time = 0.5; } elsif ($cpu_usage < 30){ $sleep_time = 1.0; } elsif ($cpu_usage < 40){ $sleep_time = 2.5; } elsif ($cpu_usage < 50){ $sleep_time = 4; } else { $sleep_time = 5; } if ($cpu_usage > 20){ print "Slowing down by ".$sleep_time." seconds...\n"; } sleep(1); } } sub thread_termination { if ($global_lock eq "RELEASED"){ threads->exit(0); } } # Create three threads my $thread1 = threads->create(\&thread_function, 1); my $thread2 = threads->create(\&thread_function, 2); my $thread3 = threads->create(\&thread_function, 3); my $thread4 = threads->create(\&thread_proc_monitor, 4); my $thread5 = threads->create(\&thread_sleep_time, 5); # Wait for the threads to complete $thread1->join(); $thread2->join(); $thread3->join(); $thread4->join(); $thread5->join();
Published by Perl Steering Council on Thursday 30 May 2024 21:22
This week it was just Paul and Philippe; we discussed the final changes for the upcoming RC2 and stable release, and marked some issues/PR as release blockers.
Graham expects to release 5.40-RC2 before the week-end.
Published by alh on Thursday 30 May 2024 08:35
Tony writes:
``` [Hours] [Activity] 2024/03/04 Monday 0.10 #22061 review and approve 0.15 #22054 review and approve 0.70 #22059 review, testing and comments 0.70 #22057 review changes, testing against App::Ack and Module::Info 0.35 #21877 debugging
3.18
2024/03/05 Tuesday
0.55
2024/03/06 Wednesday 0.10 #22063 review and approve 0.55 #21261 research and comment 0.08 #22052 review and briefly comment 0.10 #21925 recheck, apply to blead 0.57 #21686 review, work up a new patch and push for CI 1.27 #21925 work on fixes for leftover warnings, research into
2.67
2024/03/07 Thursday 0.15 #21686 review CI results, make PR 22065 0.18 #22052 research, comment and approve 1.55 #21925 commit a fix for the cast function warning, fix the wcscpy() restrict warning, testing and push for CI 0.20 #21925 review CI results, minor commit message fix, make PR 22066 1.47 #21881 testing, review code, comment, try to work out a
3.55
2024/03/11 Monday 2.20 #21261 try to reproduce i386 failure 0.08 #21261 comment 0.27 #22070 research and comment 0.55 #22071 research, review and approve
3.35
2024/03/12 Tuesday 0.40 #22070 read discussion, comment 0.80 #22068 work on fix (skip) for this and 22067 0.17 #22073 review and approve 0.15 #22075 review and approve 0.30 #22068 testing, make PR 22076
3.19
2024/03/13 Wednesday 0.15 #22024 review updates and approve 0.75 #22076 fixes and testing
2.17
2024/03/14 Thursday 0.22 #22062 comment 0.08 #22078 review and approve 1.48 #21877 debugging
2.28
2024/03/18 Monday 2.27 #22082 read discussion, work on workaround for ASAN issue, testing, make PR 22084, some updates, review change and approve 1.15 #22083 try to make blead fail based on the fix here 0.47 #22084 squash, check CI runs to a minimal point, apply to blead, research
5.22
2024/03/19 Tuesday 0.43 #22086 review and comment 0.85 #22077 review and approve 0.68 #22081 review, testing
2.23
2024/03/20 Wednesday 1.02 #22086 review latest changes and comment 1.37 #22079 research, comment
2.92
2024/03/21 Thursday 2.43 #21981 find where the desync between PL_comppad and PL_curpad happens, look for a simpler test case, work up a fix and push for CI 0.65 #21611 try profiling, some issues, doesn’t look like it’s threading
5.11
2024/03/22 Friday
0.10
2024/03/25 Monday 0.52 #22090 apply to blead, perldelta 0.32 #22097 review, research and approve 1.13 #22088 review, testing and comment
3.89
2024/03/26 Tuesday 1.33 #21877 debugging
2.68
2024/03/27 Wednesday 2.48 look over cygwin CI failures, try local test, reproduce, bisect down to the perl dll name change, research 1.47 cygwin failure: more research, testing, create issue
3.95
2024/03/28 Thursday 1.78 #22104 research, work on a workaround, testing, perldelta notes for the issue, push for CI 0.18 #22104 look over CI failure and fix 1.40 #22104 debug another issue (default static_ext being
3.36
2024/03/29 Friday
0.55
Which I calculate is 50.95 hours.
Approximately 34 tickets were reviewed or worked on, and 3 patches were applied. ```
Published by laurent_r on Tuesday 28 May 2024 22:23
These are some answers to the Week 271, 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 June 2, 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.
You are given an array of integers, @ints
.
Write a script to sort the integers in ascending order by the number of 1 bits in their binary representation. In case more than one integers have the same number of 1 bits then sort them in ascending order.
Example 1
Input: @ints = (0, 1, 2, 3, 4, 5, 6, 7, 8)
Output: (0, 1, 2, 4, 8, 3, 5, 6, 7)
0 = 0 one bits
1 = 1 one bits
2 = 1 one bits
4 = 1 one bits
8 = 1 one bits
3 = 2 one bits
5 = 2 one bits
6 = 2 one bits
7 = 3 one bits
Example 2
Input: @ints = (1024, 512, 256, 128, 64)
Output: (64, 128, 256, 512, 1024)
All integers in the given array have one 1-bits, so just sort them in ascending order.
We first build an auxiliary bit weight subroutine (bit-w
), which returns the number of 1's in the binary representation of the input integer. This is done by converting the input integer into its binary representation, using the base routine, splitting this binary representation into individual digits, and computing the sum of these digits.
We then simply sort the input array by bit weight or by value when the bit weights are equal.
sub bit-w($in) {
# bit weight function: returns number of 1s in the
# binary representation of the input integer
return [+] $in.base(2).comb;
}
sub bit-sort (@test) {
sort { bit-w($^a) cmp bit-w($^b) or $^a cmp $^b }, @test;
}
my @tests = (0, 1, 2, 3, 4, 5, 6, 7, 8),
(1024, 512, 256, 128, 64),
(7, 23, 512, 256, 128, 64);
for @tests -> @test {
printf "%-20s => ", "@test[]";
say bit-sort @test;
}
This program displays the following output:
$ raku ./sort-1-bit.raku
0 1 2 3 4 5 6 7 8 => (0 1 2 4 8 3 5 6 7)
1024 512 256 128 64 => (64 128 256 512 1024)
7 23 512 256 128 64 => (64 128 256 512 7 23)
Note that the two subroutines each have only one code line. In fact, the implementation is so simple that we could compact it into a Raku one-liner (shown here over three lines for blog post formatting reasons):
$ raku -e 'my @in = say sort { [+] $^a.Int.base(2).comb
cmp [+] $^b.Int.base(2).comb or $^a cmp $^b },
@*ARGS' 0 1 2 3 4 5 6 7 8
(0 1 8 4 2 3 5 6 7)
But I would think that the original version with two subroutines is probably clearer.
This is a port to Perl of the above Raku program. The only significant change is the use of a loop to compute the sum of the digits of the binary representation of the input integer.
use strict;
use warnings;
use feature 'say';
sub bit_w {
# bit weight function: returns number of 1s in the
# binary representation of the input integer
my $out = 0;
$out += $_ for split //, sprintf "%b", shift;
return $out;
}
sub bit_sort {
sort { bit_w($a) <=> bit_w($b) or $a <=> $b } @_;
}
my @tests = ( [0, 1, 2, 3, 4, 5, 6, 7, 8],
[1024, 512, 256, 128, 64],
[7, 23, 512, 256, 128, 64] );
for my $test (@tests) {
printf "%-20s => ", "@$test";
say join " ", bit_sort @$test;
}
This program displays the following output:
$ perl ./sort-1-bit.pl
0 1 2 3 4 5 6 7 8 => 0 1 2 4 8 3 5 6 7
1024 512 256 128 64 => 64 128 256 512 1024
7 23 512 256 128 64 => 64 128 256 512 7 23
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 June 9, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Published by laurent_r on Tuesday 28 May 2024 22:11
These are some answers to the Week 271, 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 June 2, 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.
You are given a m x n
binary matrix.
Write a script to return the row number containing maximum ones, in case of more than one rows then return smallest row number.
Example 1
Input: $matrix = [ [0, 1],
[1, 0],
]
Output: 1
Row 1 and Row 2 have the same number of ones, so return row 1.
Example 2
Input: $matrix = [ [0, 0, 0],
[1, 0, 1],
]
Output: 2
Row 2 has the maximum ones, so return row 2.
Example 3
Input: $matrix = [ [0, 0],
[1, 1],
[0, 0],
]
Output: 2
Row 2 have the maximum ones, so return row 2.
Note that, in Perl, Raku, and most programming languages, array subscripts start at 0, so that the first row of a matrix would have index 0. Here, the task specification uses common sense row ranks rather than traditional array subscripts. So we will have to add one to the index found to return a common sense row rank.
Since input is a binary matrix, i.e. populated only with 0 and 1, to find the number of ones in a row, we can simply add the items of the row, which we can do with the sum method. We just need to iterate over the matrix rows and keep track of the index of the row with the largest sum.
sub maximum-ones (@mat) {
my $max = 0;
my $max-i;
for 0..@mat.end -> $i {
my $sum = @mat[$i].sum;
if $sum > $max {
$max = $sum;
$max-i = $i;
}
}
return $max-i + 1;
}
my @tests = [ [0, 1], [1, 0] ],
[ [0, 0, 0], [1, 0, 1] ],
[ [0, 0], [1, 1], [0, 0] ];
for @tests -> @test {
printf "%-20s => ", @test.gist;
say maximum-ones @test;
}
This program displays the following output:
$ raku ./maximum-ones.raku
[[0 1] [1 0]] => 1
[[0 0 0] [1 0 1]] => 2
[[0 0] [1 1] [0 0]] => 2
This is a port to Perl of the above Raku program. We iterate over the matrix rows, compute the sum of the row items, and keep track of the index of the row with the largest sum.
use strict;
use warnings;
use feature 'say';
sub maximum_ones {
my @mat = @_;
my $max = 0;
my $max_i;
for my $i (0..$#mat) {
my $sum = 0;
$sum += $_ for @{$mat[$i]};
if ($sum > $max) {
$max = $sum;
$max_i = $i;
}
}
return $max_i + 1;
}
my @tests = ( [ [0, 1], [1, 0] ],
[ [0, 0, 0], [1, 0, 1] ],
[ [0, 0], [1, 1], [0, 0] ] );
for my $test (@tests) {
printf "%-8s, %-8s, ... => ",
"[@{$test->[0]}]", "[@{$test->[1]}]";
say maximum_ones @$test;
}
This program displays the following output:
$ perl ./maximum-ones.pl
[0 1] , [1 0] , ... => 1
[0 0 0] , [1 0 1] , ... => 2
[0 0] , [1 1] , ... => 2`
Note that we display only the first two rows of each input test matrix.
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 June 9, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Published by russbrewer on Tuesday 28 May 2024 20:55
Following up on my previous post (MariaDB 10 and Perl DBIx::Class::Schema::Loader), I wanted to try the 'deploy' feature to create database tables from Schema/Result classes.
I was surprised that I could not create a table in the database when a timestamp field had a default of current_time(). The problem was that the generated CREATE TABLE entry placed quotes around 'current_timestamp()' causing an error and rejected entry.
As mentioned in a previous post, I had created file SQL/Translator/Producer/MariDB.pm as part of the effort to get MariaDB 10 clients to work correctly with DBIx::Class::Schema::Loader. Initially it was a clone of the MySQL.pm file with name substitutions. To correct the current_timestamp problem I added a search/replace in the existing create_field subroutine in the MariaDB.pm file to remove the quotes.
# current_timestamp ?
# current_timestamp (possibly as a default entry for a
# new record field), must not be quoted in the CREATE TABLE command
# provided to the database. Convert 'current_timestamp()'
# to current_timestamp() (no quotes) to prevent CREATE TABLE failure
if ( $field_def =~ /'current_timestamp\(\)'/ ) {
$field_def =~ s/'current_timestamp\(\)'/current_timestamp\(\)/;
}
This entry is made just before the subroutine returns $field_def. Now $schema->deploy(); works correctly to create the entire database.
The code shown below was tested satisfactorily to generate CREATE TABLE output (on a per table or multi-table basis) suitable for exporting (using tables Task and User as example table names):
My $schema = db_connect();
my $trans = SQL::Translator->new (
parser => 'SQL::Translator::Parser::DBIx::Class',
quote_identifiers => 1,
parser_args => {
dbic_schema => $schema,
add_fk_index => 1,
sources => [qw/
Task User
/],
},
producer => 'MariaDB',
) or die SQL::Translator->error;my $out = $trans->translate() or die $trans->error;
I believe the SQL/Translator/Producer/MySQL.pm file would benefit from this same code addition but I have not tested using a MySQL database and DBD::mysql.
Published by Gabor Szabo on Monday 27 May 2024 05:29
Originally published at Perl Weekly 670
Hi there,
Are you regulars to Perl conference?
If yes then you have two upcoming conferences The Perl and Raku Conference in Las Vegas and London Perl and Raku Conference. Depending on your availability and convenience, I would highly recommend you register your interest to your choice(s) of conference. And if you are attending then do take the plunge give your first talk if you have not done so before. It doesn't have to be long talk, you can try quick 5 minutes lightning talk to begin with.
How about become a sponsor to the conference?
Believe it or not, it is vital that we provide financial support in the form of sponsor. So if you know someone who is in a position to support these events then please do share this TPRC 2024 Sponsors and LPW 2024 Sponsors with them. It would be a big help to organise such events.
Keynote speakers for TPRC 2024...
I came across this post by Curtis Poe where it is announced that Curtis is going to be keynote speaker at the event. Well there is a bonus for all attending the event, Damian Conway would be giving a keynote remotely. I am sure, it is going to be a memorable moment to celebrate the 25th anniversary. Similarly, London Perl Workshop would be celebrating 20th anniversary this year. I wanted to attend the TPRC 2024 in Las Vegas but for personal reason I am unable to attend. What a shame but at least I am definitely going to be part of LPW 2024 as it is local to me. No need to book travel ticket or reserve hotel room.
How many of you know about Pull Request Club?
The Pull Request Club is run by Kivanc Yazan. It started in Jan 2019. I had the pleasure to be associated with it since the beginning. I never missed the assignment until the last I contributed in January 2022. Unfortunately I faced too much distraction and missed the fun ever since. I found this annual report by the creator himself. If you like contributing to opensource projects then you should join the club and have fun.
For all cricket fans in India, did you watch the final of IPL 2024? I did and happy to see my favourite team, Kolkatta Knight Riders lifting the trophy. Although, SRH, the loosing team was my favourite too but it didn't play to their capability. I am now looking forward to the T20 World Cup next. How about you?
Today is Bank Holiday in England, so relax day for me. Enjoy rest of the newsletter. Last but not least, please do look after yourself and your loved ones.
--
Your editor: Mohammad Sajid Anwar.
In this virtual workshop you will learn why and how to use Docker for development and deployment of applications written in Perl. The workshop is free of charge thanks to my supporters via Patreon and GitHub
TPRC 2024 keynote speaker is announced. I am jealous of those able to attend the event.
Finally we have the long awaited annual report of Pull Request Club. Happy to see it is growing so fast. Congratulation to all contributors.
Being a fan of Dancer2 framework, I found this blog post very informative with plenty of handy tricks.
It is always pleasure to read about the success story of PTS 2024. Here we have another such from Kenichi. Thanks for sharing the report with us. It proves a point that Perl is in safe hand.
The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. You can even win prize money of $50 by participating in the weekly challenge. We pick one champion at the end of the month from among all of the contributors during the month, thanks to the sponsor Lance Wicks.
Welcome to a new week with a couple of fun tasks "Maximum Ones" and "Sort by 1 bits". 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.
Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Special Positions" and "Equalize Array" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Don't you love the pictorial representation of algorithm? It makes it so fun follow through the discussion. Highly recommended.
Labelled loop is not very popular among Perl fans but in certain situations it can be very handy. Check it out the reason in the post.
Classic use case of PDL, very impressive. Thanks for sharing the knowledge.
As always, we get to know any junction of Raku implementation in Perl. This is the beauty of the post every week, you don't want to skip.
Compact solutions using the power of Raku is on show. Keep it up great work.
Not sure, I have seen Luis used PDL before, I may be wrong. For me, it is encouragung to see the wide use of PDL. Keep it up great work.
This is truly incredible work, no loops at all. I would suggest, you must take a closer look. Thanks for sharing.
Well documented and crafted solutions in Perl and on top you get to play with it. Well done and keep it up great work.
Clever use of CPAN module, Math::Matrix. I always encourage the use of CPAN. Well done.
Interesting tackling of use cases. It is fun getting to the finer details. Thanks for sharing.
Just one solution this week, and typically one line analysis. Keep it up great work.
Discussion of solution in Crystal is the highlight for me. It looks easy and readable even when I know nothing about Crystal language. Highly recommended.
For Python fans, the post is always dedicated to Python only but we do receive Perl solutions. I really enjoy the compact solution in Python, specially the return list type. I never knew before. Thanks for sharing.
Great CPAN modules released last week;
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.
Published by Kenichi Ishigaki on Sunday 26 May 2024 18:14
Last year at the Perl Toolchain Summit (PTS) in Lyon, I left three draft pull requests: one about the class declaration introduced in Perl 5.37, one about the PAUSE on docker, and one about multifactor authentication. I wanted to brush them up and ask Andreas König to merge some, but which should I prioritize this year?
I focused on the web UI in the past because other people tended to deal with the PAUSE backend, especially its indexer. But this year, when I was able to start thinking about my plan, Ricardo Signes and Matthew Horsfall had already expressed their plan about migrating the PAUSE to a new server. I was unsure if they would use my docker stuff, but I could safely guess I didn't need to touch it. I also thought we wouldn't have time to finish the multifactor authentication because it would need to change the PAUSE itself and the uploader clients, and Ricardo maintained the most favorite uploader module. The change for the new class detection was simple, but that didn't mean the result would also be predictable. I decided to investigate how the 02packages index would change first.
I needed to find a way to rebuild the index from scratch to see the differences. I wrote a script to gather author information from a CPAN mirror and filled the PAUSE's user-related tables with dummy data. I wrote another script to register my distributions in the mirror to my local PAUSE. The PAUSE would complain if I registered an older distribution after a newer one, so I had to gather all the information about my distributions and sort them by creation time. It seemed fine now, but it soon started hanging up when I increased the number of the distributions to register. The PAUSE daemon spawned too many child indexer processes and ate up all the memory I allocated to a virtual machine. After several trials and errors, I limited the number of child processes with Parallel::Runner, which I used for the CPANTS for years. Even if it weren't acceptable to Andreas for some reason, it should be easy to ask for the author's help because he (Chad Granum) would be at the PTS. I also had to fix a deadlock in the database due to the lack of proper indices. Matthew had already made a pull request last year, but I misread it and fixed the issue in a different (and inefficient) way.
Now that the script ran without hanging, I compared the generated 02packages index with the one in the mirror. I found more than four thousand lines of difference. I modified my local PAUSE clone to see why that happened. It looked like most of them were removed due to historical changes in the indexing policy, but instead of digging into it further, I decided to use what I got as a reference point and started changing the indexer. After several comparisons, I modified my local indexer to take care of the byte order mark and let it look for class declarations only when a few "use" statements were found. I applied the same changes to my Parse::PMFile module and made two releases before the PTS.
Day 1 of the PTS in Lisbon started with a discussion of the PAUSE migration. While the migration team was preparing, I asked Andreas to merge some of the existing small pull requests. The first one was to replace Travis CI with GitHub Actions by Ricardo. Unfortunately, it turned out that Test::mysqld and App::yath didn't work well in the GitHub Actions environment. I asked Chad for advice, but we couldn't make it work, so I tweaked the workflow file to use the good old "prove" command. The second was to improve password generation using Crypt::URandom by Leon Timmermans. I made another pull request to add it to the cpanfile for GitHub Actions. It might be better to modify our Makefile.PL to use ExtUtils::MakeMaker::CPANfile so that we wouldn't need to maintain both cpanfile and Makefile.PL. Maybe next time.
After dealing with a few more issues and pull requests, we moved on to class detection. As a starter, I asked Andreas to merge a years-old pull request by Ricardo to make the package detection stricter and then a pull request about the BOM I made. We discussed whether we could ignore class declarations by older modules such as MooseX::Declare. With Andreas' nod, I made another pull request and asked Ricardo and Matthew to review it.
I started day two by adding tests about the class detection with Module::Faker. I made another pull request to create a new 08pumpking index per Graham Knop's request, which MetaCPAN would eventually use. After merging them and a few more pull requests, I recreated a draft pull request on the multifactor authentication with pieces I couldn't implement last year (such as recovery codes). We also discussed the deadlock issue. In the end Andreas chose my pull request plus a commit from the one by Matthew. I was sorry we encountered a disk shortage while adding indices. Robert Spier helped us and optimized the database. By the end of the day, we had a few more pull requests merged, including the one for Parallel::Runner, with the help of Chad.
Day 3 was Deployment day. The migration team was busy, and there was no room for other stuff. I walked through the open issues, replied to some, and made a few small pull requests, hoping to revisit them in the future.
On day 4, I spent some time trying to figure out why uploading a large file to the new server didn't work, but in vain. I also attended a discussion about future PAUSE development. It would be nice to see the development continue after the offline event.
Many thanks to Breno Oliveira, Philippe Bruhat, and Laurent Boivin for organizing this event again and to our generous sponsors.
Monetary sponsors: Booking.com, The Perl and Raku Foundation, Deriv, cPanel, Inc Japan Perl Association, Perl-Services, Simplelists Ltd, Ctrl O Ltd, Findus Internet-OPAC, Harald Joerg, Steven Schubiger.
In-kind sponsors: Fastmail, Grant Street Group, Deft, Procura, Healex GmbH, SUSE, Zoopla.
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.
You are given a m x n
binary matrix.
Write a script to return the number of special positions in the given binary matrix.
A position (i, j)
is called special if $matrix[i][j] == 1
and all other elements in the row i
and column j
are 0.
For the input from the command line, I take a JSON string and convert that into a list of lists of integers.
This is a break down of the steps I take to complete the task.
special_position
value to 0
.rows
and cols
to the number of rows and columns in the matrixrow_count
and col_count
with zeros for the number of rows and columns respectively.1
, increment the row_count
for the row and col_count
for the column by one. I also check that the number of items in this row is the same as the number of items in the first row.row_count
for the row is 1 (this would indicate that the other elements in the row are 0) and the col_count
is 1, add one to the special_position
variable.special_position
value.
def special_positions(matrix: list) -> int:
rows = len(matrix)
cols = len(matrix[0])
special_position = 0
row_count = [0] * rows
col_count = [0] * cols
for row in range(rows):
if len(matrix[row]) != cols:
raise ValueError("Row %s has the wrong number of columns", row)
for col in range(cols):
if matrix[row][col]:
row_count[row] += 1
col_count[col] += 1
for row in range(rows):
for col in range(cols):
if matrix[row][col] and row_count[row] == 1 and col_count[col] == 1:
special_position += 1
return special_position
$ ./ch-1.py "[[1, 0, 0],[0, 0, 1],[1, 0, 0]]"
1
$ ./ch-1.py "[[1, 0, 0],[0, 1, 0],[0, 0, 1]]"
3
You are give an array of integers, @ints
and two integers, $x
and $y
.
Write a script to execute one of the two options:
i
of the given array and do $ints[i] += 1
.i
,j
and do $ints[i] +=1
and $ints[j] += 1
.You are allowed to perform as many levels as you want to make every elements in the given array equal. There is cost attach for each level, for Level 1, the cost is $x
and $y
for Level 2.
In the end return the minimum cost to get the work done.
Before I write about my solution, it will return the expected results for the two examples, but will not always give the minimum score.
For the array (4, 4, 2) with $x
of 10 and $y
of 1, it will return 20 (perform level 1 on the third value twice). However if you perform level 2 on the first and third value (5, 4, 3), and then on the second and third value (5, 5, 4), and finally level 1 on the last value (5, 5, 5), you'd get a score of 12.
File a bug in Bugzilla, Jira or Github, and we'll fix it later :P
For input from the command line, I take the last two values to be x
and y
, and the rest of the input to be ints
.
The first step I take is to flip the array to be the number needed to reach the target value (maximum of the values).
def equalize_array(ints: list, x: int, y: int) -> str:
score = 0
# Calculate the needed values
max_value = max(ints)
needed = [max_value - i for i in ints]
I then perform level two only if y
is less than twice the value of x
. If it isn't, then I will always get the same or a lower score by performing level one on each value.
For level two, I sort the indexes (not values) of the needed
list by their value, with the highest value first. If the second highest value is 0
, it means there is no more level two tasks to perform, and I exit the loop. Otherwise I take one off the top two values in the needed
array, and continue until the second highest value is 0
. For each iteration, I add y
to the score
value.
if len(ints) > 1 and y < x * 2:
while True:
sorted_index = sorted(
range(len(ints)),
key=lambda index: needed[index],
reverse=True
)
if needed[sorted_index[1]] == 0:
break
needed[sorted_index[0]] -= 1
needed[sorted_index[1]] -= 1
score += y
Finally, my code perform the Level One operation. As level one takes one off each needed
number, I simply multiple the sum of the remaining needed
values by the x
value and add it to score
. I then return the value of score
variable.
score += sum(needed) * x
return score
$ ./ch-2.py 4 1 3 2
9
$ ./ch-2.py 2 3 3 3 5 2 1
6
Published by Unknown on Saturday 25 May 2024 22:05
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2024-05-25 20:02:08 GMT
Published by Chaitanya Agrawal on Friday 24 May 2024 19:32
You’ve conquered the Perl basics in Part 1, but the adventure continues! In Part 2, we’ll delve deeper into the world of Perl, equipping…
This article was originally published at Perl Hacks.
Over the last week or so, as a background task, I’ve been moving domains from an old server to a newer and rather cheaper server. As part of this work, I’ve been standardising the way I deploy web apps on the new server and I thought it might be interesting to share the approach I’m using and talking about a couple of CPAN modules that are making my life easier.
As an example, let’s take my Klortho app. It dispenses useful (but random) programming advice. It’s a Dancer2 app that I wrote many years ago and have been lightly poking at occasionally since then. The code is on GitHub and it’s currently running at klortho.perlhacks.com. It’s a simple app that doesn’t need a database, a cache or anything other than the Perl code.
Dancer apps are all built on PSGI, so they have all of the deployment flexibility you get with any PSGI app. You can take exactly the same code and run it as a CGI program, a mod_perl handler, a FastCGI program or as a stand-alone service running behind a proxy server. That last option is my favourite, so that’s what I’ll be talking about here.
Starting a service daemon for a PSGI app is simple enough – just running “plackup app.psgi” is all you really need. But you probably won’t get a particularly useful service daemon out of that. For example, you’ll probably get a non-forking server that will only respond to a single request at a time. It’ll be good enough for testing, but you’ll want something more robust for production. So you’ll want to tell “plackup” to use Starman or something like that. And you’ll want other options to tell the service which port to run on. You’ll end up with a quite complex start-up command line to start the server. So, if you’re anything like me, you’ll put that all in a script which gets added to the code repo.
But it’s still all a bit amateur. Linux has a flexible and sophisticated framework for starting and stopping service daemons. We should probably look into using that instead. And that’s where my first module recommendation comes into play – Daemon::Control. Daemon::Control makes it easy to create service daemon control scripts that fit in with the standard Linux way of doing things. For example, my Klortho repo contains a file called klortho_service which looks like this:
#!/usr/bin/env perl
use warnings;
use strict;
use Daemon::Control;
use ENV::Util –load_dotenv;
use Cwd qw(abs_path);
use File::Basename;
Daemon::Control->new({
name => ucfirst lc $ENV{KLORTHO_APP_NAME},
lsb_start => ‘$syslog $remote_fs’,
lsb_stop => ‘$syslog’,
lsb_sdesc => ‘Advice from Klortho’,
lsb_desc => ‘Klortho knows programming. Listen to Klortho’,
path => abs_path($0),
program => ‘/usr/bin/starman’,
program_args => [ ‘–workers’, 10, ‘-l’, “:$ENV{KLORTHO_APP_PORT}”,
dirname(abs_path($0)) . ‘/app.psgi’ ],
user => $ENV{KLORTHO_OWNER},
group => $ENV{KLORTHO_GROUP},
pid_file => “/var/run/$ENV{KLORTHO_APP_NAME}.pid”,
stderr_file => “$ENV{KLORTHO_LOG_DIR}/error.log”,
stdout_file => “$ENV{KLORTHO_LOG_DIR}/output.log”,
fork => 2,
})->run;
This code takes my hacked-together service start script and raises it to another level. We now have a program that works the same way as other daemon control programs like “apachectl” that you might have used. It takes command line arguments, so you can start and stop the service (with “klortho_service start”, “klortho_service stop” and “klortho_service restart”) and query whether or not the service is running with “klortho_service status”. There are several other options, which you can see with “klortho_service status”. Notice that it also writes the daemon’s output (including errors) to files under the standard Linux logs directory. Redirecting those to a more modern logging system is a task for another day.
Actually, thinking about it, this is all like the old “System V” service management system. I should see if there’s a replacement that works with “systemd” instead.
And if you look at line 7 in the code above, you’ll see the other CPAN module that’s currently making my life a lot easier – ENV::Util. This is a module that makes it easy to work with “dotenv” files. If you haven’t come across “dotenv” files, here’s a brief explanation – they’re files that are tied to your deployment environments (development, staging, production, etc.) and they contain definitions of environment variables which are used to control how your software acts in the different environments. For example, you’ll almost certainly want to connect to a different database instance in your different environments, so you would have a different “dotenv” file in each environment which defines the connection parameters for the appropriate database in that environment. As you need different values in different environments (and, also, because you’ll probably want sensitive information like passwords in the file) you don’t want to store your “dotenv” files in your source code control. But it’s common to add a file (called something like “.env.sample”) which contains a list of the required environment variables along with sample values.
My Klortho program doesn’t have a database. But it does need a few environment variables. Here’s its “.env.sample” file:
export KLORTHO_APP_NAME=klortho
export KLORTHO_OWNER=someone
export KLORTHO_GROUP=somegroup
export KLORTHO_LOG_DIR=/var/log/$KLORTHO_APP_NAME
export KLORTHO_APP_PORT=9999
And near the top of my service daemon control program, you’ll see the line:
use ENV::Util -load_dotenv;
That looks to see if there’s a “.env” file in the current directory and, if it finds one, it is loaded and the contents are inserted in the “%ENV” hash – from where they can be accessed by the rest of the code.
There’s one piece of the process missing. It’s nothing clever. I just need to generate a configuration file so the proxy server (I use “nginx”) reroutes requests to klortho.perlhacks.com so that they’re processed by the daemon running on whatever port is configured in “KLORTHO_APP_PORT”. But “nginx” configuration is pretty well-understood and I’ll leave that as an exercise for the reader (but feel free to get in touch if you need any help).
So that’s how it works. I have about half a dozen Dancer2 apps running on my new server using this layout. And knowing that I have standardised service daemon control scripts and “dotenv” files makes looking after them all far easier.
And before anyone mentions it, yes, I should rewrite them so they’re all Docker images. That’s a work in progress. And I should run them on some serverless system. I know my systems aren’t completely up to date. But we’re getting there.
If you have any suggestions for improvement, please let me know.
Published by Chaitanya Agrawal on Thursday 23 May 2024 01:32
Have you ever stumbled across the word “Perl” and thought, “Huh? What’s that?” Or maybe you’ve heard whispers of its cryptic symbols and…
Published by Juan Julián Merelo Guervós on Wednesday 22 May 2024 12:06
So you want to create a quick-and-dirty GitHub actions that does only one thing and does it well, or glues together several actions, or simply to show off a bit at your next work interview. Here's how you can do it.
Let me introduce you to composite GitHub actions, one of the three types that are there (the other are JavaScript GHAs or container-based GHAs) and maybe one of the most widely unknown. However, they have several things going for them. First, they have low latency: no need to download a container or to set up some JS environment). Second, they are relatively easy to set up: they can be self-contained, with everything needed running directly on the description of the GitHub action. Third, you can leverage all the tools installed on the runner like bash, compilers, build tools... or Perl, which can be that and much more.
Even being easy, it is even easier if you have a bit of boilerplate you can use directly or adapt to your own purposes. This is what has guided the creation of the template for a composite GitHub action based on Perl. It is quite minimalistic. But let me walk you through what it has got so that you can use it easier
First, this action.yml
describes what it does and how it does:
name: 'Hello Perl'
description: 'Perl Github Action Template'
inputs:
template-input: # Change this
description: 'What it is about'
required: false # or not
default: 'World'
runs:
using: "composite"
steps:
- uses: actions/checkout@v4
- run: print %ENV;
shell: perl {0}
- run: ${GITHUB_ACTION_PATH}/action.pl
shell: bash
You will have to customize inputs as well as outputs here (and, of course, name and description), but the steps are already baked in. It even includes the correct path to the (downloaded) Github action: when you're acting on a repository, the place where a GHA is is contained in an environment variable, GITHUB_ACTION_PATH
. You can access it that way.
In general, that script might need external libraries, even your own, which you might have moved out of the script for testing purposes (everything must be tested). That is why the action also contains App::FatPacker
as a dependency; that's a bundler that will put the source (action.src.pl
), your library (lib/Action.pm
) and every other module you might have used into a single file, the action.pl
referenced above.
A Makefile
is also provided, so that, after installing fatpack
, typing make
will process the source and generate the script.
And that's essentially it. Use the template and create your new (composite) action in just a few minutes!
We’re happy to confirm the return of The London Perl & Raku Workshop after a five year break:
This year’s workshop will be held at The Trampery, Old Street, a dedicated modern event space in central London. We have hired both The Ballroom and The Library; allowing us to run a main track for up to 160 attendees, and second smaller track for up to 35 attendees.
The Trampery is located a two minute walk from the Northern Line’s Old Street tube station in central London. The Northern Line has stops at most of the major train stations in London, or trivial links to others, so we recommend taking the tube to get to the venue.
If you haven’t already, please sign up and submit talks using the official workshop site
We welcome proposals relating to Perl 5, Raku, other languages, and supporting technologies. We may even have space for a couple of talks entirely tangential as we will have two tracks.
Talks may be long (40 mins), short (20 mins), or very short (aka lightning, 5 mins) but we would prefer talks to be on the shorter side and will likely prioritise 20 minute talks. We would also be pleased to accept proposals for tutorials and discussions. The deadline for submissions is 30th September.
We would really like to have more first time speakers. If you would like help with a talk proposal, and/or the talk itself, let us know - we’ve got people happy to be your talk buddy!
Thanks to this year’s sponsors, without whom LPW would not happen:
If you would like to sponsor LPW then please have a look at the options here
I was hoping to be able to write something more interesting about the GitHub Sponsors of various Perl developers, but so far I only found a few people and neither of them, well except myself, if I can still count in the group has any income via GitHub Sponsors.
Is it because they don't promote it enough?
Is it because the Explore GitHub Sponsors does not support the Perl/CPAN ecosystem?
Anyway, it would be really nice to see a few people starting to sponsors these people. That would be an encouragement to them and maybe also to others to support them.
If you'd like to read more such posts, don't forget to upvote this one, to follow me here on DEV.to and to sponsor me via GitHub Sponsors.
(picture from elevate)
For various reasons, you might want to install CPAN modules from a git repository.
It can be because somehow a git repository is in advance against CPAN:
Or it can be because the modules are actually not in CPAN: not public and not in a alternative/private CPAN (see Addendum) or simply they are only "experiments"
But this post is not meant to discuss about the "why" but instead mainly share technically the "how" you could do that 😀
I tested various syntax and installers and will share now some working examples.
☝️ Before we continue, be sure to upgrade your installers (App::cpm
and App::cpanminus
) to their latest
cpm
Installing with cpm
is straighforward:
$ cpm install https://github.com/plack/Plack.git --verbose
33257 DONE fetch (0.971sec) https://github.com/plack/Plack.git
33257 DONE configure (0.033sec) https://github.com/plack/Plack.git
33257 DONE resolve (0.031sec) Clone -> Clone-0.46 (from MetaDB)
...
33257 DONE install (0.364sec) URI-5.28
33257 DONE install (0.046sec) https://github.com/plack/Plack.git
31 distributions installed.
It can also work the same with ssh git@github.com:plack/Plack.git
:
$ cpm install git@github.com:plack/Plack.git --verbose
64383 DONE fetch (2.498sec) git@github.com:plack/Plack.git
64383 DONE configure (0.039sec) git@github.com:plack/Plack.git
...
64383 DONE install (0.045sec) git@github.com:plack/Plack.git
31 distributions installed.
cpanminus
Installing with cpanm
is not harder:
$ cpanm https://github.com/plack/Plack.git
Cloning https://github.com/plack/Plack.git ... OK
--> Working on https://github.com/plack/Plack.git
...
Building and testing Plack-1.0051 ... OK
Successfully installed Plack-1.0051
45 distributions installed
cpanfile
The correct syntax is the following (thank you @haarg):
requires 'Plack', git => 'https://github.com/plack/Plack.git', ref => 'master';
(ref => 'master'
is optional)
And it would just work later with cpm
:
$ cpm install --verbose
Loading requirements from cpanfile...
33257 DONE fetch (0.971sec) https://github.com/plack/Plack.git
33257 DONE configure (0.033sec) https://github.com/plack/Plack.git
33257 DONE resolve (0.031sec) Clone -> Clone-0.46 (from MetaDB)
...
33257 DONE install (0.364sec) URI-5.28
33257 DONE install (0.046sec) https://github.com/plack/Plack.git
31 distributions installed.
⚠️ Despite being a cpanfile
, please note the use of cpm
cpmfile
Let's write our first cpmfile and save it as cpm.yml
:
prereqs:
runtime:
requires:
Plack:
git: https://github.com/plack/Plack.git
ref: master
And then it would just work with cpm
:
$ cpm install --verbose
Loading requirements from cpm.yml...
66419 DONE resolve (0.000sec) Plack -> https://github.com/plack/Plack.git@master (from Custom)
66419 DONE fetch (1.695sec) https://github.com/plack/Plack.git
66419 DONE configure (0.034sec) https://github.com/plack/Plack.git
...
66419 DONE install (0.023sec) https://github.com/plack/Plack.git
31 distributions installed.
Releases on CPAN are standardized and generally contain what is needed for installers, but distributions living in git repositories are more for development and very often not in a "ready to install" state.
(thank you @karenetheridge)
There's some limitations that you can encounter:
cpm
would refuse to install if no META file is found (but cpanm
would be OK with that)cpm
would refuse to install if no Makefile.PL
nor Build.PL
is found, except if x_static_install: 1 is declared in META (cpanm
would still refuse) Should I mention the repositories with only a dist.ini
? (used by authors to generate everything else)
And you would get similar trouble with distributions using Module::Install
but having not versioned it.
You should probably not rely too much on "install from git" method but still, it can provide an handy way to install modules to test fixes or experiments.
And now with this post you should have good examples of “how” you can achieve that.
For alternative/private CPAN, several tools can come to your rescue:
Published by Unknown on Sunday 19 May 2024 09:06
Published on Thursday 16 May 2024 19:00
The Perl and Raku Conference (now in its 26th year) would not exist without sponsors. Above, you’ll see a screen shot from Curtis Poe’s Perl’s new object-oriented syntax is coming, but what’s next? talk at last year’s conference in Toronto. You may be wondering how you can add your organization’s logo to this year’s list. In the spirit of transparency, we are making our sponsorship prospectus public. Please share this article freely with friends, colleagues and decision makers so that we can reach as many new sponsors as possible.
This year the Perl and Raku Conference will be held in Las Vegas, Nevada on June 24-28, 2024. Conferences such as this provide tangible benefits to organizations which use Perl. Aside from the transfer of knowledge which attendees bring back to their place of work, on-site hackathons also contribute to the growth and maintenance of the software stack which so many companies have come to rely on. In 2022, for example, the hackathon focused on modernizing and improving support for Perl across various editors, allowing Perl developers to be even more productive than they have been in the past.
There are still opportunities to support this important, grassroots Open Source Software event. Events like these largely depend on sponsors in order to thrive.
This year, we are looking for corporate donations to offset the costs of feeding conference attendees. Each of these sponsorship opportunities comes with the following:
Sponsor a catered breakfast during one of the conference days
Sponsorship commitment: $3,500
Sponsor a catered snack break during one of the conference days.
Sponsorship commitment: $3,000
Sponsor a coffee break during one of the conference days.
Sponsorship commitment: $2,500
Please do let me know at what level you might be interested in contributing and we can begin the process of getting you involved in this very special event.
In order to get your logo on the “step and repeat” banner we would need to have finalized sponsorship and received logo assets by June 1st, so we’d love to help you start the process as soon as you’re ready.
For any questions or to begin the sponsorship process, please contact me via olaf@wundersolutions.com. I’ll be happy to answer any questions and walk you through the process. If you’d like to discuss sponsorship options which are greater or smaller than the offerings listed, I can also work with you on that. If you’re not ready to sponsor this event but would like to be included in future mailings, please reach out to me via email as well. I look forward to hearing from you!
In 2024 we expect to host over 100 attendees, but there is a hard cap of 150. If you’re thinking of attending, it’s best to secure your ticket soon.
Published by Unknown on Sunday 12 May 2024 09:43
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2024-05-12 07:32:36 GMT
Published by Makoto Nozaki on Thursday 09 May 2024 19:21
TL;DR We just finished intern selection for this year’s Outreachy program. We got more projects and more applicants than the previous years, which made the selection hard in a good way.
Continuing our annual tradition, The Perl and Raku foundation is involved in the Outreachy program which provides internships to people subject to systemic bias and impacted by underrepresentation.
We have just finished the intern selection process, which turned out to be harder compared to the previous years. I’ll explain the reasons below.
Each year, we call for project ideas from the Perl/Raku community. Project proposer is required to commit to mentoring an intern from May to August. Given the significant commitment involved, it’s not uncommon for us to find suitable projects.
Fortunately, this year, we got two promising project proposals. The Foundation’s financial situation did not allow us to sponsor both projects, so we had to make the tough decision to support only one project.
After careful consideration, the Board has elected to sponsor Open Food Fact’s Perl project, titled “Extend Open Food Facts to enable food manufacturers to open data and improve food product quality.”
Having more projects means we were able to attract more intern candidates. Across the two projects, more than 50 people showed interest and initiated contributions. Among them, 21 individuals actually created pull requests before the selection process.
Needless to say, it's hard work for the mentors to help dozens of candidates. They taught these intern candidates how to code and guided them through creating pull requests. On the applicants’ side, I am amazed that they worked hard to learn Perl and became proficient enough to create pull requests and make real improvements to the systems.
After the contribution process, we got an application from 14 people. It was obviously hard for the mentors to select one from so many good applicants. In the next post, Stéphane Gigandet will introduce our new intern to the community.
I wish all the best to the mentors, Stéphane and Alex, and our new intern.
"In the journey to understand Perl better, I wanted to know what are its most wide applications, one of them being a web scraper. It's because Perl's strong support for regular expressions and built-in text manipulation functions make it well-suited for tasks like web scraping, where parsing and transforming text are essential. I took inspiration from various web scraping projects available on the internet to gain insights into the process and developed a lyrics scraper."
"I'm currently diving into Perl, and I see this as a fantastic chance to enrich my coding skills. I've thoroughly enjoyed immersing myself in it and have had the opportunity to explore various technologies like Docker and more."
"I have had the opportunity to experience Perl firsthand and have come to appreciate its significance in web development, on which I have worked. During my second year, I was searching for popular languages in backend development and found out about Perl, whose syntax was somewhat like C and Python. I didn't have any previous experience working with Perl, but now I have gained a deep understanding of its importance and impact on backend development and data processing."
"In this pull request, I made a significant stride in improving the quality and maintainability of our Perl codebase by integrating Perl::Critic, a powerful static code analysis tool."
"I've learned a whole lot about Perl and some of its frameworks such as Dancer2 (a surprisingly simple framework I've come to fall in love with)."
Welcome to “What’s new on CPAN”, a curated look at last month’s new CPAN uploads for your reading and programming pleasure. Enjoy!
Published by alh on Monday 06 May 2024 19:42
Tony writes:
``` [Hours] [Activity] 2024/02/01 Thursday
2.50
2024/02/02 Friday 0.72 #21915 review, testing, comments
0.97
2024/02/05 Monday 0.25 github notifications 0.08 #21885 review updates and approve 0.57 #21920 review and comment 0.08 #21921 review and approve 0.12 #21923 review and approve 0.08 #21924 review and approve 0.08 #21926 review and approve 0.67 #21925 review and comments
3.93
2024/02/06 Tuesday 0.23 #21925 comment 0.52 review coverity scan report, reply to email from jkeenan 0.27 #21927 review and comment 0.08 #21928 review and approve
1.18
2024/02/07 Wednesday 0.25 github notifications 0.52 #21935 review, existing comments need addressing
2.89
2024/02/08 Thursday 0.40 #21927 review and approve 0.23 #21935 review, check each comment has been addressed, approve 0.45 #21937 review and approve 0.15 #21938 review and comment 0.10 #21939 review and approve 0.13 #21941 review and approve 0.10 #21942 review and approve 0.08 #21943 review and approve 0.07 #21945 review and approve 0.17 #21877 look into CI failures, think I found problem, push probable fix 0.18 #21927 make a change to improve pad_add_name_pvn() docs, testing, push for CI 2.20 #21877 performance test on cygwin, try to work up a
4.26
2024/02/12 Monday 0.60 #18606 fix minor issue pointed out by mauke, testing 0.40 github notifications 0.08 #21872 review latest changes and approve 0.08 #21920 review latest changes and approve 1.48 #21877 debugging test 0.30 #21524 comment on downstream ticket
3.21
2024/02/13 Tuesday 0.35 #21915 review, brief comment 0.25 #21983 review and approve 0.03 #21233 close 0.28 #21878 comment 0.08 #21927 check CI results and make PR 21984 0.63 #21877 debug failing CI 0.27 #21984 follow-up 0.58 #21982 review, testing, comments
2.79
2024/02/14 Wednesday 1.83 #21958 testing, finally reproduce, debugging and comment 0.08 #21987 review discussion and briefly comment 0.08 #21984 apply to blead 0.22 #21977 review and approve 0.12 #21988 review and approve 0.15 #21990 review and approve 0.82 #21550 probable fix, build tests 0.38 coverity scan follow-up 1.27 #21829/#21558 (related to 21550) debugging
5.60
2024/02/15 Thursday 0.15 github notifications 0.08 #21915 review updates and approve 2.17 #21958 debugging, research, long comment 0.58 #21958 testing, follow-up
3.10
2024/02/19 Monday 0.88 #21161 review comment and reply, minor change, testing, force push 0.23 #22001 review and comment 0.30 #22002 review and comment 0.12 #22004 review and comment 0.28 #22005 review and approve 0.32 #21993 testing, review changes 1.95 #21661 review comments on PR and fixes, review code and
4.08
2024/02/20 Tuesday 0.35 github notifications 0.08 #22010 review and approve 0.08 #22007 review and approve with comment 0.60 #22006 review, research and approve with comment 0.08 #21989 review and approve 0.58 #21996 review, testing, comment 0.22 #22009 review and approve 0.50 #21925 review latest updates and approve
3.54
2024/02/21 Wednesday 0.18 #22011 fixes 0.80 #21683 refactoring
2.78
2024/02/22 Thursday 0.38 #22007 review and comment 0.70 #21161 apply to blead, perldelta as PR22017 1.75 smoke report checks: testing win32 gcc failures 0.27 #22007 review updates and approve
4.25
2024/02/26 Monday 2.10 look over smoke reports, debug PERLIO=stdio failure on mac
3.48
2024/02/27 Tuesday 0.08 #22029 review and apply to blead 0.27 #22024 review and approve 0.33 #22026 review and approve 0.08 #22027 review and approve 0.10 #22028 review and approve 0.08 #22030 review and comment, conditionally approve 0.25 #22033 review, comments and approve 0.08 #22034 review and approve 0.17 #22035 review and comment
2.22
2024/02/28 Wednesday 0.38 github notifications 0.52 #22040 review discussion, research and comment 0.13 #22043 review and approve 0.12 #22044 review and approve 0.72 #22045 review, research, comment and approve 0.13 #22046 review, research and approve
3.55
2024/02/29 Thursday 0.15 #21966 review update and approve 1.18 #21877 debugging
1.46
Which I calculate is 55.79 hours.
Approximately 70 tickets were reviewed or worked on, and 5 patches were applied. ```
Published by Makoto Nozaki on Friday 03 May 2024 19:49
I am pleased to announce that The Perl and Raku Foundation sponsored the Perl Toolchain Summit 2024 as a Platinum Sponsor.
The Perl Toolchain Summit (PTS) is an annual event where they bring together the volunteers who work on the tools and modules at the heart of Perl and the CPAN ecosystem. The PTS gives them 4 days to work together on these systems, with all their fellow volunteers to hand.
The event successfully concluded in Lisbon, Portugal at the end of April 2024.
If you or your company is willing to help the future PTS events, you can get in touch with the PTS team. Alternatively, you can make a donation to The Perl and Raku Foundation, which is a 501(c)(3) organization.