Published by Martian2020 on Monday 25 September 2023 00:41
Examples on stackoverflow involving -s switch
(e.g. https://stackoverflow.com/a/29613573/14557599) give position of --
like:
perl -s -e 'if ($xyz) { print "$xyz\n" }' -- -xyz
perldoc perlrun
:
-s enables rudimentary switch parsing for switches on the command line after the program name but before any filename arguments (or before an argument of --). Any switch found there is removed from @ARGV and sets the corresponding variable in the Perl program. The following program prints "1" if the program is invoked with a -xyz switch, and "abc" if it is invoked with -xyz=abc. #!/usr/bin/perl -s if ($xyz) { print "$xyz\n" }
I'm confused with "before an argument of --", because example above works, -xyz is after --
. If written as in docs:
perl -xyz -- -s -e 'if ($xyz) { print "$xyz\n" }'
Can't open perl script "-s": No such file or directory
Per my understanding how it works I want to write in doc:
after the program name (or after an argument of --) but before any filename arguments
Is my change correct? Maybe sometime before syntax of perlrun was indeed as described in docs but was changed later but docs were updated to reflect that?
Edit 2:
After reading all the answers:
after the program name (or after first occurrence of an argument of -- if the program is specified via -e or -E switches) but before any filename arguments (or before --, first occurrence in case of program name and second in case of the program specified via -e or -E switches)
Edit:
In response to am answer by zdin (note: I have not found definition of option
, switch
; seems those are synonyms and both are used as both bash command line arguments and in perl program on shebang line arguments).
echo a-a-a > 1.txt
q.pl
#!/usr/bin/perl -sp
s/a/b/;
if ($xyz) { print "$xyz\n" }
w.pl
#!/usr/bin/perl -s
s/a/b/;
if ($xyz) { print "$xyz\n" }
I can call *.pl passing 1.txt as argument w/out --
:
./q.pl -xyz=a 1.txt
a
b-a-a
perl -p ./q.pl -xyz=a 1.txt
a
b-a-a
One-liner:
perl -spe 's/a/b/;if ($xyz) { print "$xyz\n" }' -- -xyz=a 1.txt
a
b-a-a
That shows my reformulation is valid for both running via program name and one-liners.
P.S.
perl --version
This is perl 5, version 34, subversion 0 (v5.34.0) built for x86_64-linux-gnu-thread-multi
Published by w.k on Monday 25 September 2023 00:34
I wrote a script to watermark images. On command line adding watermark works fine:
composite -dissolve 5% -gravity South watermark.png original.jpg new.jpg
Now when I tried to use Perlmagick for watermarking, the composite part does not change anything:
my $i = new Image::Magick;
my $watermark = $i->Read( "watermark.png" );
my $i2 = new Image::Magick;
my $p = $i->Read( "original.jpg" );
$i->Set( Gravity => 'Center' );
$i->Resize( geometry => "600x600" );
$i->Composite( image=>$watermark, compose=>"Dissolve", opacity=>5, gravity=>"South" );
$i->Write( 'jpg:temp_file' );
Such script resizes image, but does not watermark it.
Problem seems to be in the way I provide dissolving degree. On command line I can add percentage to dissolve-attribute, but in API version dissolve is itself attribute. I tried with opacity, but this seems not the right way too.
What is the right way to use dissolve in Perlmagick?
Published by tonycoz on Monday 25 September 2023 00:24
Revert "[perl #89544] Non-eval closures don’t need CvOUTSIDE" But they do need CvOUTSIDE() for eval-in-package-DB's scope magic to work correctly. This also incidentally fixes a TODO Deparse, since the CvOUTSIDE is now available Fixes #19370 aka rt89544 This breaks #11286, but I don't think that's fixable without breaking eval-in-DB's special scope behaviour. This reverts (most of) commit a0d2bbd5c47035a4f7369e4fddd46b502764d86e.
Published by tonycoz on Monday 25 September 2023 00:24
add TODO tests for 19370
Published by tonycoz on Monday 25 September 2023 00:13
feature: document feature bundle ':all' and why you don't use it Fixes #17209
Published by tonycoz on Monday 25 September 2023 00:11
regcomp_debug.c: change a mis-use of ASSUME() to STATIC_ASSERT_STMT() As mauke points out in #21490 the compiler "knows" all of the constants here at compile-time, so the ASSUME()s here do nothing. I suspect the intent here was to ensure that we never overflow the capacity of the flags parameter, which we can check at compile-time with STATIC_ASSERT_STMT(). mauke also suggested using CHAR_BIT instead of 8, but Configure probes for CHARBITS and the perl core generally uses CHARBITS, so use that here too.
Published by tonycoz on Monday 25 September 2023 00:11
regdump_intflags: there is no PL_reg_intflags_name[REG_INTFLAGS_NAME_SIZE] Yes, this is an old report, from 2014. cid29034
Published by Birendra Singh on Sunday 24 September 2023 17:18
I am stuck while running the project which has been created on Perl with Mojolicious module. here is the code of the file from where I am running the project using morbo command
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
use Mojolicious::Commands;
$ENV{MOJO_USERAGENT_DEBUG} = 1;
# Start command line interface for application
Mojolicious::Commands->start_app('Reports');
All modules has been installed successfully and trying to run the project using morbo command. I am getting the error while running the project. Not sure why even each module and files are there. also Server.pm file is there in the specified path.
Please help me to run this project. The project is in Perl and ep templates for CPAN. Please confirm what I am missing to run the project.
Published by Simon Green on Sunday 24 September 2023 10:06
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 an array of integers.
Write a script to find out if removing ONLY one integer makes it strictly increasing order.
When I first read the challenge (which I do on public transport on Monday evenings usually), the approach I was going to take was to remove one item at a time and check if the list is in increasing order.
Then I thought I would be cleaver and wrote code that counted the number of times a value was lower than the previous value. This would provide the correct results for the three examples. If that occurred more than once, then it is false.
However when I started writing this blog post, I realized a floor in my logic. Taking the sequence '8, 9, 1, 2, 3' would have returned true even though you couldn't remove a single value to make an incremental list.
My second attempt was to loop through the list once and see how many times the value is less than the current maximum. If this occurs more than once, it means there is no solution. However, this would fail for the list '8, 1, 2, 3' where it would return false when you could remove the 8 to pass the test.
So in the end, I went back to the original plan. Remove one number from the list, check if it is incrementing. Print true if it, print false
if we exhaust all tests.
My final code looks like this
# Loop through each position of the list
for i in range(len(ints)):
# Make a new list with the integer at that position remove
new_list = ints.copy()
del new_list[i]
# Check if the list is incremental
if all(new_list[j-1] <= new_list[j] for j in range(1, len(new_list))):
# It is, tell the user about it
print('true')
return
# Oh dear. No solution is possible
print('false')
Had this being done in the real world, this is where I would talk with colleagues to figure out if this can be optimized more.
$ ./ch-1.py 0 2 9 4 6
true
$ ./ch-1.py 5 1 3 2
false
$ ./ch-1.py 2 2 3
true
You are given an array of integers.
Write a script to duplicate each occurrence of ZERO in the given array and shift the remaining to the right but make sure the size of array remain the same.
After the previous task, this should be easier. It also shows up short comings of my Python knowledge compared to Perl. So lets start with the Perl solution as it's straight forward. Generate a new list using the map function, and then use the splice function to truncate it.
my @solution = map { $_ ? $_ : ( 0, 0 ) } @ints;
splice( @solution, scalar(@ints) );
The Python solution does the same, but is a little more verbose. There is probably a way to do this more efficiently. After writing this blog post, I'll look at other peoples solutions.
for i in ints:
# Add the original number
solution.append(i)
if i == 0:
# Add it twice if it is zero
solution.append(i)
solution = solution[:len(ints)]
$ ./ch-2.py 1 0 2 3 0 4 5 0
1, 0, 0, 2, 3, 0, 0, 4
$ ./ch-2.py 1 2 3
1, 2, 3
$ ./ch-2.py 0 3 0 4 5
0, 0, 3, 0, 0
Published by jimav on Sunday 24 September 2023 00:21
Is there a way to make auto-encoding file handles use specified Encode
flags?
Specifically I want to make STDOUT and STDERR use the Encode::FB_PERLQQ flag so any characters which can not be encoded are output as \x{ABCD} instead of garbage + a nasty warning message.
More specifically, I want to use open ':locale'
to auto-detect whatever encoding the environment expects, and modify STDOUT & STDERR to use that encoding but with the flag Encode::FB_PERLQQ
in effect. I imagine doing something like
use open ':locale'; # determine what the environment expects
my @layers = PerlIO::get_layers(*STDOUT);
my ($encoding) = ("@layers" =~ /encoding\((.*?)\)/);
binmode(*STDOUT, "something which means $encoding with flags Encode::FB_PERLQQ")
My application is Perl module test cases, which are automatically run on many smoker machines all over the internet, including some Windows hosts using the cp850 character set. If I just make test scripts encode to UTF-8 then on those machines some characters appear as garbage; I would rather see the \x{...} fallback enabled by FB_PERLQQ so the code-point could be determined from the logs.
Published by mikeLundquist on Saturday 23 September 2023 20:39
I have this perl script that uses switches and strict warnings.
#! /usr/bin/perl -s
use strict;
$some = $some . " more";
print "got $some\n";
When I run it at the command line I get these errors.
$ ./strictTest.pl -some=SOME
Variable "$some" is not imported at ./strictTest.pl line 3.
Variable "$some" is not imported at ./strictTest.pl line 3.
Variable "$some" is not imported at ./strictTest.pl line 4.
Global symbol "$some" requires explicit package name (did you forget to declare "my $some"?) at ./strictTest.pl line 3.
Global symbol "$some" requires explicit package name (did you forget to declare "my $some"?) at ./strictTest.pl line 3.
Global symbol "$some" requires explicit package name (did you forget to declare "my $some"?) at ./strictTest.pl line 4.
Execution of ./strictTest.pl aborted due to compilation errors.
What can I do to get perl to recognize that $some
is defined because it's passed as a switch?
Published by /u/niceperl on Saturday 23 September 2023 20:22
Published by Unknown on Saturday 23 September 2023 22:21
Published by Unknown on Saturday 23 September 2023 22:13
This is the weekly favourites list of CPAN distributions. Votes count: 45
Week's winner: Mojo::IOLoop::ReadWriteProcess (+3)
Build date: 2023/09/23 20:12:50 GMT
Clicked for first time:
Increasing its reputation:
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2023-09-23 20:11:27 GMT
Published by Perl Steering Council on Saturday 23 September 2023 20:06
There were only two of us this week, and the list is still a bit quiet.
The main topic was stalled PPC work: we have a few PPCs that have been approved and are in the “Implementing” state, but still waiting for an implementor. We’ll send a separate email asking for volunteers on those.
Published by Perl Steering Council on Saturday 23 September 2023 19:59
Two of us again, here's the summary of our meeting:
A Rust friend is attempting to convert me through this tutorial
Published by /u/singe on Saturday 23 September 2023 16:47
Here's an example of a small error that bit me surprisingly hard recently.
I like to construct print messages. I like a robust approach, so I do like one way that Python handles printing (e.g. print("{}".format(val)) )
I recently made a small mistake in a "say" statement:
say __LINE__. " Current symbols: ". scalar(@$arf)." ==> ".. join(" ;; ", @$arf);
The code compiles. The Perl checker (-c) didn't catch the error and I was (probably) too tired to see it right away.
Now I'm going to add a check for ".." in my custom syntax checker. ^_^
Here's an old post about a print statement with placeholders. Look at the lovely hack offered by u/tobotic. (Some commenters threw some scorn my way. Yay gnarly programmers. ^_^ )
https://old.reddit.com/r/perl/comments/e4fnvs/a_meditation_print_statement_with_placeholders/
Published by oldtechaa on Saturday 23 September 2023 05:19
Hi everybody, we've got another two challenges this week, so let's dive into them!
The goal is to see if there's any one number that can be removed to make the set sorted in increasing order. Here's the code:
#!/usr/bin/perl
use v5.36;
my $success = 0;
REMOVAL: for my $removal (0 .. $#ARGV) {
my @modified = @ARGV;
splice(@modified, $removal, 1);
for my $scan (1 .. $#modified) {
if($modified[$scan] <= $modified[$scan - 1]) {
next REMOVAL;
}
}
$success = 1;
last;
}
say ($success ? 'true' : 'false');
We have a labelled outer loop for the numbers we choose to remove. $removal is set to the index of each number we attempt to remove, then we copy the array, remove that number, and scan the result to make sure they all are increasing. If they don't, we skip this number and move on.
If we succeed, we set our flag and exit the loops and print the result.
The next one is an array shifting challenge. We want to insert a duplicate of each 0, shifting everything to the right, and popping off the list to keep the length the same.
Here's the code:
#!/usr/bin/perl
use v5.36;
my @ints = @ARGV;
for(my $i = 0; $i <= $#ints; $i++) {
if($ints[$i] == 0) {
splice(@ints, $i, 0, 0);
pop(@ints);
$i++;
}
}
say('(', join(', ', @ints), ')');
This one's also really quite simple. We scan the array, use splice to insert a 0, pop the last number off the end of the array, and skip over the 0 we just inserted. It's that simple!
Both of this week's solutions make use of splice() to insert and remove array elements, something I haven't used a lot before.
Stay tuned for next week's challenge, which should come out Monday!
Published by oldtechaa on Saturday 23 September 2023 00:16
Hi everybody, we've got another two challenges this week, so let's dive into them!
The goal is to see if there's any one number that can be removed to make the set sorted in increasing order. Here's the code:
#!/usr/bin/perl
use v5.36;
my $success = 0;
REMOVAL: for my $removal (0 .. $#ARGV) {
my @modified = @ARGV;
splice(@modified, $removal, 1);
for my $scan (1 .. $#modified) {
if($modified[$scan] <= $modified[$scan - 1]) {
next REMOVAL;
}
}
$success = 1;
last;
}
say ($success ? 'true' : 'false');
We have a labelled outer loop for the numbers we choose to remove. $removal is set to the index of each number we attempt to remove, then we copy the array, remove that number, and scan the result to make sure they all are increasing. If they don't, we skip this number and move on.
If we succeed, we set our flag and exit the loops and print the result.
The next one is an array shifting challenge. We want to insert a duplicate of each 0, shifting everything to the right, and popping off the list to keep the length the same.
Here's the code:
#!/usr/bin/perl
use v5.36;
my @ints = @ARGV;
for(my $i = 0; $i <= $#ints; $i++) {
if($ints[$i] == 0) {
splice(@ints, $i, 0, 0);
pop(@ints);
$i++;
}
}
say('(', join(', ', @ints), ')');
This one's also really quite simple. We scan the array, use splice to insert a 0, pop the last number off the end of the array, and skip over the 0 we just inserted. It's that simple!
Both of this week's solutions make use of splice() to insert and remove array elements, something I haven't used a lot before.
Stay tuned for next week's challenge, which should come out Monday!
Published by /u/dkech on Friday 22 September 2023 22:20
I uploaded System::CPU to CPAN, a pure Perl module with no dependencies to get basic CPU info across various platforms. The main function of interest is:
my ($phys_processors, $phys_cpu, $logical_cpu) = System::CPU::get_cpu();
i.e. giving you separately processors (sockets, physical cores, logical cores/hyperthreads). You also have get_name
, get_arch
, get_name
and get_ncpu
which is almost the same as MCE::Util::get_ncpu
(i.e. borrowing code), as that function was the most consistent at getting the number of logical cores.
Anyway, it is what I ended up using for my Benchmark::DKbench CPU benchmark suite, as all the modules I tried were either missing things, had inconcistencies or could not be installed on some systems. The hardware summary from the benchmark suite ends up looking like this:
--------------- Hardware --------------- CPU type: Intel Xeon CPU @ 2.60GHz (x86_64) CPUs: 176 (2 Processors, 88 Cores, 176 Threads)
And after running the suite single and multi-threaded, the summary looks like this:
DKbench summary (19 benchmarks, 176 threads): Single: 1001 Multi: 86076 Multi/Single perf: 86.01x (63.39 - 125.09) Multi scalability: 48.9% (36% - 71%)
I've been using this benchmark to evaluate some large cloud instances like the above, so it can scale to hundreds of cores (MCE), but if you want to bench your desktop/laptop give it a try and tell me if I can do something better ;)
Published by alh on Friday 22 September 2023 12:13
Tony writes: ``` [Hours] [Activity] 2023/08/01 Tuesday 0.20 look at new coverity hits, briefly discuss with khw 0.27 github notifications 0.87 #21306 review and briefly comment 0.05 #21084 check latest CI results, apply to blead 0.13 #21296 test blead with the fix, close this PR 0.28 coverity look at older hits, one harmless, another false positive (in the context of perl) 0.18 #21181 apply to blead, perldelta 0.42 #21212 comment
3.68
2023/08/02 Wednesday 0.08 #21306 review new changes and approve 0.37 #21304 comment 3.05 #21313 debugging
5.92
2023/08/03 Thursday 0.23 #21000 review and comment 1.18 #21323 review and comment 1.50 #21313 make a more portable change and testing 0.98 #21313 clean up and more testing, psuh to PR 21324 1.20 #21313 debugging remaining test failure - turns out to be
5.09
2023/08/07 Monday 1.92 #21313 research, minor fix, apply to blead, perldelta 0.27 #21314 apply to blead, check if docs need update 0.77 #21313 re-work patch for remaining bug, pr perl- libwin32/win32#39
4.06
2023/08/08 Tuesday 0.68 github notifications 0.07 #21325 review and trigger CI 0.43 #21333 review, code archaeology: why was SIG localized? ask for a test case 0.23 #21325 add to authors, bump strict version and apply to blead 0.08 #21328 review and approve 0.82 #21334 review and approve with a comment 0.08 #21335 review and approve 0.12 #21336 review and approve 0.10 #21337 review and approve (and watch github flake out) 0.03 #21338 review and approve 0.05 #21339 review and approve 1.55 #20890 debugging, try to understand how this is meant to
4.24
2023/08/09 Wednesday 0.75 github notifications 0.22 more github notifications 0.53 #21333 review and approve, comment 0.25 #21331 comment 0.20 #21340 review and comment 0.73 #21341 review, research, comment and approve 0.10 #21342 review and approve 0.08 #21343 review and approve 0.37 #21344 review and approve 0.08 #21345 review and apply (had another approval) 0.18 #21346 review, testing and comment
3.56
2023/08/10 Thursday 0.25 github notifications 1.22 #21340 review modifications, research, comments 0.90 #21347 review and melt brain 0.53 #21332 work up a fix and make PR 21359
4.40
2023/08/14 Monday 0.30 #21347 review and approve 0.07 #21355 review and approve 0.90 #21358 review and comment 0.33 #21359 apply to blead, perldelta 0.27 #21361 review and approve
1.97
2023/08/15 Tuesday 0.17 #21340 follow up 0.05 #21333 apply to blead 1.20 #21375 review and comments 0.45 #21376 try to reproduce CI failure, reproduce and comment 0.10 #21377 review and approve
2.59
2023/08/16 Wednesday 0.38 #21375 follow up comment 0.05 #21376 review after changes and approve 0.35 ppc#25 comments 0.65 #21379 research and comment
1.60
2023/08/17 Thursday 0.23 ppc#25 follow-up comment 0.13 #21385 review and comment 0.25 #21375 re-review and comment
0.68
2023/08/21 Monday 0.22 #21387 follow-up and close 0.20 #21350 research and comment 0.30 #20917 rebase, testing 0.97 #20917 more testing, push for re-CI (don’t pass until corelist update) 0.07 #21379 check latest changes and approve 0.05 #21395 review and approve 0.02 #21407 review and apply to blead
1.95
2023/08/23 Wednesday 0.13 #20917 rebase on corelist fix 0.12 #19426 rebase on corelist fix 0.17 #21329 re-check and apply to blead, perldelta 0.13 #21394 review and comment 0.38 #21392 review and approve 0.13 #21391 review and approve 0.40 #21351 review and approve 0.47 #21415 research 2.15 #21415 testing, yet another cop_features fix, more
4.08
2023/08/24 Thursday 0.95 #21415 testing, polish, make PR 21421 0.63 #21419 review and comments
2.35
2023/08/28 Monday 0.40 #21431 review, research and comment 0.20 #21419 comment 0.15 #21411 comment 1.52 #21415 re-work 0.72 #21415 more re-work and push 0.28 #21390 review and comments
3.70
2023/08/29 Tuesday 0.10 #21390 review updates and approve 0.62 #21415 updates 0.10 #21420 review and apply to blead 0.37 #21422 review 0.37 #21422 more review, approve
2.36
2023/08/30 Wednesday 0.28 #21419 look over updates 0.15 #21433 review and comment 1.80 #21434 review and approve 0.23 #21428 review, testing and comment
4.09
2023/08/31 Thursday 0.12 #21433 review changes and apply to blead 0.05 #21428 review changes and approve 1.15 #21421 apply to blead, perldelta 0.28 #21435 review and approve 0.10 #21436 review and approve
2.27
Which I calculate is 58.59 hours.
Approximately 73 tickets were reviewed or worked on, and 13 patches were applied. ```
Published by lichtkind on Thursday 21 September 2023 21:40
Whohoo release 1.7 (and 1.6) brought a thorough architectural rewrite, new color spaces (HSV, HWB, YIQ), new formats ([named] array, string and css_string), choosable value ranges, closed both open issues, and introduced the named argument API I wrote last time about. And as promised, this post is about the methods: distance, set, add and blend.
Color Properties
Yes GTC gives you color sets, but how do you know a color, from which you calculate the set, has all the right properties? Many of these properties you simply get by converting the values into color spaces like HSL or HWB. So:
$color->values( in => 'HSL', as => hash )->{lightness};
$color->values( in => 'CMYK', as => hash )->{cyan};
($color->values( 'CMYK' ))[0]; # same thing but shorter
my $d = $color->distance( to => $other_color, in => 'HWB');
$color->distance( to => $other, in => 'HSL', select => 'hue');
$color->distance( to => $other, in => 'HSL', select => 'ssl');
$color->distance( to => $other, range => 'normal');
Related Colors
Beside the obvious constructor method new, there are 3 more methods that create an color object, which has a relation to the current object.
The simplest one of then is set. It replaces some values of the current object with the given. Its full power comes from the ability to accept values in all supported color space. This gives us the ability to create an brown with a certain brightness, but immediately output the values in another format.
color('brown')->set( brightness => 70 )->values( 'CMYK' );
While set changes to an absolute value, add performs relative changes. To slightly dim a Pink we just need:
color('pink')->add( lightness => -10 );
$color->blend( with => 'grey', pos => 0.1); # we fade to gray
I'm often asked why I created Venus, and I typically give an answer that amounts to "It's complicated" or "Have you looked at language X" which I concede is unsatisfying to most; so in this article, I will attempt to explain in a more precise and concise manner, for the record.
Why I created Venus
If you survey and analyze the features offered across programming languages used in modern software engineering you'll recognize what I call a "baseline feature set for modern software development". In my opinion, this is missing from the Perl programming language. It's achievable but missing in the sense that it's not core and it's not packaged in a way that's easily accessible.
Some examples are support for data encoding, reflection, gradual typing, object orientation, concurrency, error handling, a robust standard library, etc.
Getting to a modern software engineering baseline in Perl, in 2023, means
traversing a vast landscape filled with potential landmines. To do so successfully means having a firm grasp of the language and its idioms, as well as a familiarity with the CPAN and the best-in-class distributions.
Venus was created to alleviate that pain!
Maybe it's never occurred to you that getting to a modern software engineering baseline in Perl is a nearly impossible feat for someone new to programming, or new to Perl, or simply looking to "get shit done".
Venus, with its convention over configuration object-oriented architecture, is meant to feel familiar to engineers coming from other (modern) languages, looking (or needing) to work in Perl. Venus helps to answer questions like, "How do I create an array object that comes preset with methods that allow me to perform common array operations, which can be chained together?", etc.
Venus provides a robust standard library, embodies industry standards, enables object-orientation and reflection, has sophisticated and extendable exception handling, offers a library of abstract behaviors (i.e. roles/traits), and is built atop an intuitive convention over configuration architecture.
In the coming articles, I will further demonstrate the why and how of Venus, using code examples, comparisons, and real-world software challenges.
See for yourself!
Published by laurent_r on Wednesday 20 September 2023 18:04
These are some answers to the Week 235, 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 September 24, 2023 at 23:59). This blog post offers 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.
Write a script to duplicate each occurrence of ZERO in the given array and shift the remaining to the right but make sure the size of array remain the same.
Example 1
Input: @ints = (1, 0, 2, 3, 0, 4, 5, 0)
Ouput: (1, 0, 0, 2, 3, 0, 0, 4)
Example 2
Input: @ints = (1, 2, 3)
Ouput: (1, 2, 3)
Example 3
Input: @ints = (0, 3, 0, 4, 5)
Ouput: (0, 0, 3, 0, 0)
We don't really know what should happen if keeping the array size leads to the removal of the zero just added. We will assume the added zero is just chopped off, like this:
Input: @ints = (0, 3, 2, 0, 4)
Ouput: (0, 0, 3, 2, 0)
The duplicate-zeros
subroutine uses the map
function to build a new array in which any zero from the input array is repeated and other values are just copied untouched. After that, the subroutine returns a splice of the resulting array having the size of the input array.
sub duplicate-zeros (@in) {
my @result = map { $_ == 0 ?? |(0, 0) !! $_ }, @in;
return @result[0..@in.end];
}
for <1 0 2 3 0 4 5 0>, <1 2 3>, <0 3 0 4 5> -> @test {
printf "%-18s => ", "@test[]";
say duplicate-zeros @test;
}
This program displays the following output:
$ raku ./duplicate-zeros.raku
1 0 2 3 0 4 5 0 => (1 0 0 2 3 0 0 4)
1 2 3 => (1 2 3)
0 3 0 4 5 => (0 0 3 0 0)
This Perl program does the same thing as the above Raku program. Please refer to the above section for any explanation.
use strict;
use warnings;
use feature 'say';
sub duplicate_zeros {
my @result = map { $_ == 0 ? (0, 0) : $_ } @_;
return @result[0..$#_];
}
for my $test ([<1 0 2 3 0 4 5 0>],
[<1 2 3>], [<0 3 0 4 5>]) {
printf "%-18s => ", "@$test";
say join " ", duplicate_zeros @$test;
}
This program displays the following output:
$ perl ./duplicate-zeros.pl
1 0 2 3 0 4 5 0 => 1 0 0 2 3 0 0 4
1 2 3 => 1 2 3
0 3 0 4 5 => 0 0 3 0 0
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 October 1, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.
Published by Bob Lied on Wednesday 20 September 2023 12:47
I always try to find the common theme between the tasks in the weekly challenge, and I will just straight up invent one if I have to. What I see in week 235 is two tasks that are about moving down a list in a quirky way. The blog title? Moving down a list in pairs reminded me of the slide
function, and that reminded me of a minor hit from the Moody Blues circa 1978, Steppin' in a Slide Zone.
That invoked a nostalgic digression to listen to the whole album (downloaded in minutes from 45 years ago -- we live in a marvelous age). I am distressed by the number of brain cells that are uselessly calcified with lyrics of obscure songs from a half-century ago, when they could be so much better used storing obscure Perl programming facts.
You are given an array of integers.
Write a script to find out if removing ONLY one
integer makes it strictly increasing order.
Input:
@ints = (0, 2, 9, 4, 6)
Output:true
Removing ONLY 9 in the given array makes it strictly increasing order.
Input:
@ints = (5, 1, 3, 2)
Output:false
Input:
@ints = (2, 2, 3)
Output:true
I was misled by examples that are too easy. My impulse was to look for the number of times that the sequence descends instead of ascends, and report if that number was more than one. However, that doesn't cover the case where removing an element still leaves the list with a descending step. For instance, the list (10 20 30 18 19 40)
has only one downward step, but we need to remove at least two elements to get to sorted. Back to this after an interlude of how to do it wrong.
Even though I started with a bad solution, it illuminated some topics of list iteration, so let's look at ways of finding the descending steps in a sequence. The motion is two-at-a-time, and there are several ways of doing that.
The basic way, similar in many languages, is to move an index from 0 to not quite the end, and compare $ints[$i]
and $ints[$i+1]
. Counting downward steps is a necessary but insufficient condition, so we're including that.
sub removeOne(@ints)
{
my $rmvCount = 0;
for ( my $i = 0; $i < $#ints && $rmvCount < 2 ; $i++ )
{
$rmvCount++ if $ints[$i+1] < $ints[$i];
}
return $rmvCount < 2;
}
When we're given a list, it's always tempting to manipulate the list as a whole with map
and similar functions, which often helps with tricky boundary conditions. We can apply map
to pairs of the list by using indexes in the same way as the for loop -- excluding the very last index at the boundary, and mapping each pair of integers to a boolean that says whether the pair is ascending or descending. Then a count of the descending pairs (false
) will tell us how many might need to be removed.
sub removeOne(@ints)
{
my $rmvCount = grep { $_ == false }
map { $ints[$_] < $ints[$_+1] } 0 .. ( $#ints-1 );
return $rmvCount < 2;
}
Another very Perl-ish way to process pairs at a time is to shift elements off the array, consuming the array in the process.
my $first = shift @ints;
while ( defined (my $next = shift @ints ) )
{
say "PAIR: ($first, $next)";
$first = $next;
}
Perl v5.36 added the ability in for
loops to iterate over successive tuples of an array. That's not quite what we want here, because it moves two elements in every iteration, but it's worth a mention.
for my ($first, $second) (1,2,3,4) { say "$first, $second" }
# 1, 2
# 3, 4
Pair-at-a-time list iteration is common enough that there is a module for it: List::MoreUtils::slide
applies a block to each pair in sequence, attaching the names $a
and $b
to the elements for the convenience of a code block. Using slide
is probably the most readable version (assuming one knows what slide
does).
sub removeOne(@ints)
{
use List::MoreUtils qw/slide/;
my $rmvCount = 0;
slide { $rmvCount++ if ( $b < $a ) } @ints;
return $rmvCount < 2;
}
Both the map
and the slide
solution suffer from a potential inefficiency that often plagues array operations: they operate on the entire array, even if we could discover the answer in the first elements of the array.
One way we could make slide
give up sooner is to throw an exception from the block. Perl has had exception modules available for years, but in 5.36 try/catch/finally
became [an experimental] part of the language. Here's a way to break out of slide before it wastes time:
sub removeOne(@ints)
{
use List::MoreUtils qw/slide/;
use feature 'try'; no warnings "experimental::try";
my $rmvOne = true;
try {
my $rmvCount = 0;
slide { do { die if ++$rmvCount > 1 } if ( $b < $a ) } @ints;
}
catch ($e)
{
$rmvOne = false;
}
return $rmvOne;
}
But back to actually solving the problem. We still have the sub-problem of finding a descending step in the sequence. Take 10 20 30 24 25 40
as an example. Which elements should we remove to create a sorted list?
When we hit a down step, we have a choice of what to remove: we can either remove the greater elements to the left until we get back in order, or we can remove the lesser elements to the right until we start ascending again. If we can do it by removing one, we might succeed; if we have to remove more in either direction, we fail.
10 ^ 20 ^ 30 V 24 ^ 25 ^ 40
10 20 [30] <== 24 25 40 # Go back
10 20 30 ==> [24 25] 40 # Skip ahead
The tricky part of this solution is the likelihood of off-by-one errors to take care of the out-of-order element being at the beginning or end of @ints
. Here's code that literally walks backward and forward from the point of disorder:
sub removeOne(@ints)
{
use List::Util qw/min/;
return true if @ints < 3;
my $rmvCount = 0;
# Walk forward until we hit a descending step.
for ( my $i = 0 ; $i < $#ints && $rmvCount < 2 ; $i++ )
{
next if $ints[$i+1] >= $ints[$i];
# How far backward would we have to go to get back in order?
my $back = 0;
for ( my $j = $i ; $j >= 0
&& $ints[$j] > $ints[$i+1]
&& $back < 3;
$j-- )
{
$back++;
}
# How far ahead would we have to go to get back in order?
my $ahead = 0;
for ( my $j = $i+1; $j <= $#ints
&& $ints[$j] <= $ints[$i]
&& $ahead < 3;
$j++ )
{
$ahead++;
}
$rmvCount += min($back, $ahead);
}
return $rmvCount < 2;
}
Consider a sequence like ( 1000, 1..999, 2000)
. It would be a waste of time moving ahead 1000 steps to rediscover order. We never really need to move backward or forward more than two steps to know the answer. An optimization is to include that condition in the back and forth motions.
I use unit testing frameworks to make sure I don't break one boundary condition when I fix another. These are my test cases:
sub runTest
{
use Test2::V0;
no warnings "experimental::builtin";
is( removeOne(0,2,9,4,6), true, "Example 1");
is( removeOne(5,1,3,2 ), false, "Example 2");
is( removeOne(2,2,3 ), true, "Example 3");
is( removeOne(10,1,2,3 ), true, "First element goes");
is( removeOne(10,11,1 ), true, "Last element goes");
is( removeOne(10,20,30,24,25,40), true, "One high peak");
is( removeOne(10,20,30,18,25,40), false, "One high, one low");
is( removeOne(1,2,5,3,4,6,3,4), false, "Multiple disorders");
is( removeOne(99, 1000, 1..999, 2000), false, "Long failure");
done_testing;
}
One note: I use true
and false
booleans, which were introduced as experimental built-in functions in 5.36. Annoyingly, they emit warnings, so the incantation to put at the top of the file is
use builtin qw/true false/; no warnings "experimental::builtin";
The Test2::V0
testing module re-enables all warnings, so the suppression of warnings has to be repeated after the module is invoked.
You are given an array of integers.
Write a script to duplicate each occurrence of
ZERO in the given array and shift the remaining
to the right, but make sure the size of array
remains the same.
Input:
@ints = (1, 0, 2, 3, 0, 4, 5, 0)
Output:(1, 0, 0, 2, 3, 0, 0, 4)
Input:
@ints = (1, 2, 3)
Output:(1, 2, 3)
Input:
@ints = (0, 3, 0, 4, 5)
Output:(0, 0, 3, 0, 0)
Two approaches come to mind: we could insert all the zeroes where required and then truncate the list to its original length; or we could walk down the list, inserting one zero at a time and lopping off the right-most element each time. The first approach will double the space required for the list. The second will take no extra space, but needs a little more care in bookkeeping.
First, let's try substituting every occurrence of 0 with a pair of zeros:
map { $_ || (0,0) } @ints
This concise little tidbit exploits two features of Perl. First, 0 is a false value and all other numbers are true-ish. That means that every time $_
is non-zero, it will be true, so the expression will return $_
itself and not evaluate the right side of the ||
operation. When $_
is zero, the left side is false, and the right side gets evaluated. We've cleverly made the right side be a pair of zeros. Perl does not build an array of arrays from this; it flattens the list.
So now we have a list where every 0 has been doubled. It is too long. We can truncate it by taking a slice that's as long as the original list. To do that, we'll take the result of map
as an array and apply an index range to it.
(map { $_ || (0,0) } @ints)[0 .. $#ints]
The other approach would be to walk along the list and modify it explicitly each time we find a zero. Let's do this a couple of ways. First, let's copy input to output and add the zero in the process of copying:
sub dz_A(@ints)
{
my $maxLen = @ints;
my @output;
while ( @output < $maxLen )
{
push @output, shift @ints;
push @output, 0 if ( $output[-1] == 0 && @output < $maxLen );
}
return \@output;
}
A few Perl notes: in @output < $maxLen
, we're exploiting the fact that naming an array in a scalar context returns the length of the array. Instead of tracking an index to move along the input, we're consuming the input with a shift
operation. And finally, we can index from the end of @output
with -1 to look at the number we just moved, avoiding a temporary variable.
The other strategy I considered for this solution is to modify the list in place. Each time we find a zero, splice an extra zero into the list, and pop off the right end of the list to keep it the same length.
sub dz_B(@ints)
{
for (my $i = 0 ; $i <= $#ints; $i++ )
{
if ( $ints[$i] == 0 )
{
# Insert a zero and advance i past it
splice(@ints, $i++, 0, 0);
pop @ints; # Maintain the length;
}
}
return \@ints;
}
Notice that we used post-increment of $i
to move the index ahead to the next value in @ints
instead of processing the newly-inserted zero in the next loop iteration.
If 1978 is ancient history, pretend I referenced Goo Goo Dolls "Slide" from 2002.
Published by Saif Ahmed on Wednesday 20 September 2023 09:53
A new grant application from John Napiorkowski and Robert Grimes, this time targetting the development of a large language model trained specifically to develop Perl Code. These veteran coders suggest that using natural language to generate Perl code may potentially allow one to rapidly generate new APIs and applications, or at least give a skeleton to flesh out into a more elaborate tool.
John Napiorkowski & Robert Grimes
The budget for this project is $8,800 USD, to be made in one lump-sum payment upon completion.
This amount is calculated by multiplying the estimated minimum total hours labor (220 hours) by the minimum acceptable hourly rate for an open source Perl project ($40 / hour):
(220 hours) * ($40 / hour) = $8,800 USD
Please note this amount does NOT include the high cost of renting or purchasing the necessary GPU hardware equipment, which will graciously be donated by the ChatGPU.ai group as a service to the Perl community.
This grant proposal is for phase 1 of the development of PerlGPT, a large language model (LLM) comparable to ChatGPT 4.0, and trained on additional Perl-related content only. PerlGPT will be based on Meta's Code Llama (from Llama v2 or newer) language models, with all new components implemented in Perl where possible and released as free-and-open-source software (FOSS), unlike ChatGPT and other proprietary LLM systems.
Code Llama: Open Foundation Models for Code
Code Llama's documentation currently lists the following primarily-supported languages: "Python, C++, Java, PHP, TypeScript, C#, and Bash". One of the outcome of the PerlGPT project will be to effectively add Perl to this list. (PerlGPT may ultimately be released under an alternative name, such as "Perllama".)
Phase 1 consists of training a 13B input language model using Perl-related stimulus/response pairs curated from Perl Monks, Stack Overflow, GitLab, GitHub, and other public Perl-specific data sources. Phase 1 will deliver an LLM capable of generating pure-Perl source code in collaboration with a Perl programmer, similar to Microsoft Bing and GitHub Copilot.
As with the Perl TensorFlow grants, PerlGPT "is a long-term multi-phase grant series, aimed at radically changing the perception of Perl in the modern software development and AI industries."
(This grant proposal has been simplified and re-submitted, per the request of TPF's grant committee.)
Phase 1 implements PerlGPT v1.0 and benefits the Perl community by enabling the creation of new pure-Perl libraries and applications on CPAN.
PerlGPT v1.0 is trained on pure-Perl source code examples and high-quality POD documentation from CPAN, GitLab, GitHub, and Bitbucket. PerlGPT is further trained on plain-English technical discussions pertaining to their respective feature set, gathered from Perl Monks and Stack Overflow.
For example, a programmer may want to create a new Perl API for some 3rd-party web platform such as the Amazon cloud. The programmer can write a plain-English description of their desired API features and functionality for accessing the Amazon cloud. They can also specify design decisions such as whether or not to utilize an MVC framework like Catalyst or Mojolicious, and they can even start stubbing out some Perl classes and subroutines with comments included where source code should be added.
In this example, PerlGPT v1.0 will work with the programmer to iteratively implement their desired Amazon cloud API in pure Perl, including a full-coverage test suite and POD documentation, etc. Once the API is working well enough for public release, the PerlGPT v1.0 LLM can even help the programmer execute the correct Dist::Zilla commands to build and upload the software to CPAN. Finally, many new independent Perl projects can be created with access to the Amazon cloud, thanks to the Perl API created and uploaded to CPAN with the help of PerlGPT v1.0!
These same benefits apply to any other non-Amazon API which somebody may want to create in Perl, or to any pure-Perl library or application that a programmer can think up. The sky is the limit! PerlGPT v1.0 dramatically increases the effectiveness and efficiency of creating new pure-Perl software.
We will generate the PerlGPT language model by training a Llama foundational language model. This training will be done using a combination of both manually-curated and automatically-selected stimulus/response pairs, collected from public websites and data sources. We will not utilize any proprietary data or stimulus/response training sets taken from other proprietary language models, such as OpenAI's ChatGPT, etc.
Most of the technical details of how to train the PerlGPT language model can be found in the following papers:
Training Language Models to Follow Instructions with Human Feedback, 3-4-2022
Teaching Large Language Models to Self-Debug, 4-11-2023
LLaMA: Open and Efficient Foundation Language Models, 2-27-2023
Total development time is estimated at 3 to 6 months, with the normal disclaimer about the difficulty of predicting software project durations.
During the first work cycle of approximately 1 to 2 months, curate and implement the initial PerlGPT v1.0 training data set.
During the second work cycle, run the LLM training procedure and implement the Perl test suite. (The training may take a particularly long time on our currently-available GPU hardware, due to limitations in available grant funding for renting very expensive high-end GPU hardware.)
During the third work cycle, write the Perl documentation and implement the Perl example applications.
If a fourth work cycle is required, continue until the public releases on CPAN and DockerHub are complete.
This grant is deemed complete when all the above-listed deliverables are reviewed and accepted by the official TPF-assigned grant manager.
We are both professional CPAN authors, with a current total of 98 CPAN distributions between the two of us.
John is the maintainer of Catalyst:
The Perl Foundation sponsored the Perl TensorFlow API phase 1, and we recently worked with our colleagues Will Braswell and Zaki Mughal to successfully utilize and showcase Perl TensorFlow in the new ChatGPU Navi AI system:
Introduction to TensorFlow in Perl
We both live in the Austin, Texas area.
Published on Wednesday 20 September 2023 06:00
TL;DR
Schwern wrote a little gem.
Some time ago I wanted to import a few CSV files in one SQLite database file and I initially tried to do it with Perl. It was sloooooow.
Then I looked for alternatives and found out .import
from the
command-line client sqlite3
. This is reasonably fast, so I used it
straight away and forgot about it.
Until I came to read Schwern’s little gem, hinting
to turn AutoCommit
off. That hit the nail so good that one single hit
sufficed.
So here’s an example:
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
use DBI;
use Text::CSV_XS;
my $csv_file = shift // help_then_die('no CSV file');
my $sqlite_file = shift // help_then_die('no SQLite file');
my $sqlite_table = shift // help_then_die('no SQLite table name');
my $csv_it = csv_it($csv_file);
my $fields = $csv_it->();
my $dbh = DBI->connect("dbi:SQLite:$sqlite_file", '', '',
{ RaiseError => 1, AutoCommit => $ENV{AUTOCOMMIT}, }
);
say scalar(localtime);
$dbh->do(sqlite_create_query($dbh, $sqlite_table, $fields));
$dbh->commit unless $ENV{AUTOCOMMIT};
my $sth = $dbh->prepare(sqlite_insert_query($dbh, $sqlite_table, $fields));
while (my $row = $csv_it->()) {
$sth->execute($row->@*);
}
$dbh->commit unless $ENV{AUTOCOMMIT};
say scalar(localtime);
sub sqlite_create_query ($dbh, $table, $fields) {
my $q_table = $dbh->quote_identifier($table);
my $fields_def = join ",\n", map { " $_ TEXT" } $fields->@*;
return "CREATE TABLE IF NOT EXISTS $q_table (\n$fields_def\n)";
}
sub sqlite_insert_query ($dbh, $table, $fields) {
my $q_table = $dbh->quote_identifier($table);
my $fields_def = join ', ', $fields->@*;
my $pholds_def = join ', ', ('?') x scalar($fields->@*);
return "INSERT INTO $q_table ($fields_def) VALUES ($pholds_def)";
}
sub csv_it ($path, %args) {
my $csv = Text::CSV_XS->new(
{
sep_char => ',',
%args,
}
) or die Text::CSV_XS->error_diag;
open my $fh, '<:encoding(UTF-8)', $path
or die "open('$path'): $!\n";
return sub { return $csv->getline($fh) };
}
sub help_then_die ($msg) {
say {*STDERR} "$0 <csv-file> <sqlite-file> <sqlite-table>\n";
die $msg, "\n";
}
Test time:
$ rm -f local/prova.db; time AUTOCOMMIT=1 perl csv2sqlite local/somedata.csv local/prova.db whatever
Tue Sep 19 23:08:39 2023
Tue Sep 19 23:09:30 2023
real 0m50.788s
user 0m0.134s
sys 0m6.149s
$ rm -f local/prova.db; time AUTOCOMMIT=0 perl csv2sqlite local/somedata.csv local/prova.db whatever
Tue Sep 19 23:10:21 2023
Tue Sep 19 23:10:21 2023
real 0m0.174s
user 0m0.118s
sys 0m0.023s
This is what I call a speed improvement!
Cheers!
Published by Johnathan Swan on Monday 18 September 2023 16:51
5 years ago, I shared how we had recently started using Perl::Critic, specifically with Test::Perl::Critic::Progressive, to gradually…
Published by Johnathan Swan on Monday 18 September 2023 16:50
5 years ago, I shared how we had recently started using Perl::Critic, specifically with Test::Perl::Critic::Progressive, to gradually…
Published by Gabor Szabo on Monday 18 September 2023 04:17
Originally published at Perl Weekly 634
Hi there,
Only recently we had a big bang release of Perl v5.38 with experimental class feature. Now in a quick succession we have another release Perl v5.39.1. Thanks to the entire team responsible for the release. These heroes work behind the scene for days/months for the improvement of the language. Yet, I rarely see anyone giving them credit on public platform. We should not just mention them in the pod but instead celebrate each one of them more on various public platforms. Having said, we need volunteer for the job. Do we have volunteer for the task?
Few days ago, I had an email from someone senior with lots of experience with Perl saying "2023 is the year the language died for him". I wonder how can someone just gave up on the language you loved all your life. For me personally, Perl will remain my core strength and I will continue to improve my knowledge with every release. It is OK if you learn some new languages to be in the job market but please keep Perl your first choice.
Yesterday, when I was done with Asia Cup 2023 final cricket match between India and Sri Lanka, I watched this documentary, The Great Hack, on Netflix. It reminded me data is the new oil now a days. Perl is known to be good at data processing, so why are we behind others in this field?
By the way, India won the final for the 8th time. I am so proud of Team India. I am now looking forward to the World Cup 2023 to be held in few months time in India.
Enjoy rest of the newsletter.
--
Your editor: Mohammad S. Anwar.
The day-of-week for any day in the year range 1-5000000 Julian. (Doesn't do BC yet; I need to make some changes to the algorithm first.) It also does conversion between Gregorian and Julian.
Continue with the multipart blogs, here the discussion is about regex engine maps to a finite state automaton, we should be able to rewrite the parser without regular expressions, using flags to keep track of the part of the record we are at.
In the final part of this series, we will test the performance of the four parsers, in a scenario emulating the batch analysis of sequencing data.
Do you play with constants in Perl often then do check this post, you would love it.
CGI::Tiny is a very nice, Perlish way to construct CGI scripts these days. It is perfectly suited as a replacement to CGI.pm and is quite at home in a shared hosting environment.
The Weekly Challenge by Mohammad Anwar will help you step out of your comfort-zone. You can even win prize money of $50 Amazon voucher by participating in the weekly challenge. We pick one winner at the end of the month from among all of the contributors during the month. The monthly prize is kindly sponsored by Peter Sergeant of PerlCareers.
Welcome to a new week with a couple of fun tasks: "Remove One" and "Duplicate Zeros". If you are new to the weekly challenge, 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 "Common Characters" and "Unequal Triplets" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Great CPAN modules released last week;
StackOverflow Perl report.
If you’re a Modern Perl developer in the UK with TypeScript or Node and you’re searching for a team of dynamos, we’ve found the perfect place for you. This award-winning company may be newer, but the combined experience of their people is impressive. No doubt this is one of the many reasons their AI recruitment marketing business has taken off!
Our client is a global leader in the enterprise technology publishing industry, providing audiences worldwide with stimulating perspectives and unique news on enterprise tech that matters today and tomorrow. They are seeking a talented Perl programmer to manage the full life-cycle of software projects on a remote basis.
Our UK-based client is a global leader in the enterprise technology publishing industry, providing audiences worldwide with stimulating perspectives and unique news on enterprise tech that matters today and tomorrow. They are currently seeking a passionate and exceptional Perl programmer based in the Philippines to join their team.
Clever folks know that if you’re lucky, you can earn a living and have an adventure at the same time. Enter our international client: online trading is their game, and they’re looking for solid Perl people with passion, drive, and an appreciation for new experiences.
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 Grosu Alexandra Elena on Sunday 17 September 2023 20:31
Perl is one of the oldest and most widely used languages for web application development.
Published by Grosu Alexandra Elena on Sunday 17 September 2023 13:46
Perl is a versatile and powerful programming language that has been used for web development for decades. Perl offers many frameworks and…
Published by Unknown on Sunday 17 September 2023 08:47
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2023-09-17 06:42:34 GMT
Published by Amber Deuel on Thursday 14 September 2023 18:16
The first ever Perl and Koha conference was held in Helsinki, Finland this year. It featured three main days of Perl and Koha presentations and two days of workshops. Workshops included a Perl training session, a masterclass for new Koha developers, Koha improvement initiatives, discussions on the future of Perl as a language, and more.
Koha is the first free open source software library automation package. In use worldwide its development is steered by a growing community of users. Koha is a framework developed in Perl with modules stored on CPAN. Koha allows end users to borrow books from within district and national library systems. A large number of attendees were Koha front end users that are primarily made up of librarians. Perl community members made up an estimated third of attendees. While the connection between these two communities may not be obvious, they benefit from working together.
I was graciously given time to interview two attendees, Salve and Julien, they say there was room for cross interaction between Koha and Perl during talks and workshops, and speakers from both gave talks about mentoring that were attended by members from both communities. Community members also interacted during lightning talks and social events, such as the reception. The reception was held in the National Library in Helsinki and was impressive to the attendees.
Most of the people involved with Koha are librarians looking to make their lives better at work. In the eyes of some attendees, coding is something you do to reach a goal and Perl is well matched with Koha because of this. Koha also has a strong community, similar to our Perl community. Open source projects like Koha can save schools and public libraries thousands of dollars.
Finally, both of the interviewees found the opening talks especially moving. Olga Dibrova, The Ukrainian ambassador to Finland, was a surprise speaker at the opening. She spoke about the devastating impact the Russian invasion has caused on Ukrainian libraries and the urgency to rebuild those structures once it can be safely done. Perl/Koha conference organizer Andrii, also supports Ukrainian libraries and has created a project to help rebuild not only structures, but also the book collections that have been burned during the war. For more information about the Ukrainian Libraries help and post-war restoration initiative, visit https://perlkohacon.fi/ULRI.html .
Next year the conference will be held in Montreal, Canada.
Published by alh on Thursday 14 September 2023 08:37
Dave writes:
This is my monthly report on work done during June-August 2023 covered by my TPF perl core maintenance grant.
I fixed a performance regression bug related to my 'multiconcat' optimisation work from about 5 years ago.
Other than that, I restarted my work on my "make stack reference counted" branch, got it into a working state, and merged it into blead. See below for a detailed explanation.
SUMMARY:
TOTAL: * 79:00 (HH::MM)
Understanding the "stack not reference counted" issue.
I've been asked to include an explanation as to why "making the perl stack reference counted" is a Good Thing, and why it's burning up so many hours in TPF funding.
Internally, perl is mainly based around Scalar Value (SV) structures,
which hold a single value. Entities such as $x
or $a[0]
are all SVs. These
SVs include a reference count (RC) field which, when it reaches zero,
triggers the freeing of the SV. For the basics, consider the following
code:
sub f {
my $x = ...;
my $y = ...;
return \$y;
}
my $ref = f();
On return from the function, the SV associated with $x
is freed in a
timely manner. This is because its RC starts as 1, and is reduced to 0 on
scope exit. Conversely, the SV bound to $y
has its RC increased to 2 by a
reference being taken to it, then back down to 1 when $y
goes out of
scope. So it lives on, accessible as $$ref
. This is all good.
Now, perl is a stack-based engine. Internally this means that it has a stack of pointers to SVs, and such pointers are pushed on and popped off as perl executes ops. For example, the action of perl's '+' operator is to:
For brevity's sake, I shall in future refer to "pushing an SV" where I mean "pushing a pointer to an SV onto the argument stack".
Now we come to the issue. As a "premature optimisation", perl doesn't increase an SV's RC when pushing onto the stack, nor decrease it when popping. This has the obvious danger that an SV could be be freed while still on the stack, and thus something like an add operator could access a freed SV (and thus undef value), or even worse, the SV could have been reallocated in the meantime and have a completely unrelated value.
Related to this, the @_
argument array doesn't normally reference-count
its contents. For normal arrays, the expression $a[0] = "abc"
will
create an SV, which has the value "abc", and which has a RC of 1 to
account for the pointer to the SV which is stored in the array. When the
array is freed, the RC of each SV in the array is decremented, and so the
elements of the array are typically freed too. @_
doesn't do this.
Instead, when a function is called, the arguments are pushed onto the
stack (without the RC being bumped), then the list of SV pointers are
moved from the stack into @_
, again without the RCs being adjusted.
Thus items in @_
are in danger of being prematurely freed.
Here is a classic example of the bug. Examine this code carefully:
@a = qw(aaa bbb);
f(@a);
sub f {
# on entry, $_[0] is an alias of $a[0],
# $_[1] is an alias of $a[1],
print "@_\n"; # correctly prints "aaa bbb"
@a = (); # this prematurely frees $_[0] and $_[1]
# this causes the two just-freed SVs to be reallocated
my $x = 'xxx:yyy'; my @x = split /:/, $x;
# but the two reallocated SVs are still referenced by @_
print "@_\n"; # incorrectly prints "xxx yyy"
}
This may sound horrendous, and in a way it is. Put in practice, this
doesn't happen as often as you might expect. There is usually something
else keeping the elements of @_
alive, so the bug is rarely encountered
in day-to-day code. But when it does, it can be difficult to track down.
Also, it sabotages code-fuzzers. From time to time, volunteers run jobs which create perl "programs" out of small random fragments and attempt to run them. If one crashes (in the sense of a SEGV or ASAN error), then that indicates a bug in the perl interpreter itself. However, we stopped accepting such bug reports, becuase the vast majority of them turned out to be variants on "stack not refcounted", but it was taking some time to analyse each report and reach that conclusion.
So fixing this bug would be a Good Thing. However, it turns out that fixing it is rather hard. This design flaw has been in the heart of the perl core for 25+ years, and there's about 30,000 lines of C code directly related to implementing all the stack operators (basically just about every op in perl works from the stack).
In particular, it's an all-or-nothing situation: you can't have half the ops adjusting reference counts when pushing/popping while the other half leave them unadjusted.
The way I eventually worked out how to achieve this was by initially wrapping nearly every op function (around 300 of them) with code that adjusts the reference counts of all its arguments on the stack, calls the "real" function, then adjusts any return values in the stack.
This allowed a "big switch" to be turned on in one go that activated reference counting across the entirety of the perl core.
Then in relative leisure, each individual function can be re-written to work directly on an RC stack and not require slow wrapping.
The initial wrapping work, involving around 70 commits, was merged into blead on 16th August. from that point it is now possible to build a perl with the PERL_RC_STACK configuration option which will now run safely, fixing at least least 70 issue tickets and allowing fuzzers to be be used again, while running approximately 30% slower (based on approximate time to run the test suite).
A second set of commits, merged on 4th Sept, unwrapped many of the common and/or easy ops, leaving around 140 out of 314 still to unwrap. At a very rough glance this is now around 10% slower than "vanilla" blead. I haven't done any proper benchmarking yet, though - I plan to do that after I've unwrapped all the hot ops.
Note that none of this work (or at least, very little) currently affects a default build of the perl interpreter: it is only when perl is built with the PERL_RC_STACK option that reference-counting is enabled. Without that, perl behaves and performs just as before (although many of the ops have now been rewritten to use a new API to manipulate the stack: which in theory should behave in a non-changed way on non-PERL_RC_STACK builds).
It is intended that eventually, PERL_RC_STACK will become the default, and then the only, build option.
There is still much work to be done, including
Published by Grosu Alexandra Elena on Wednesday 13 September 2023 23:59
Perl, a versatile and powerful programming language, extends far beyond its reputation as a command-line tool. While Perl has long been…
Published on Tuesday 12 September 2023 06:00
TL;DR
If you happen to have a deck of the Decktet, you can easily play Skull too:
That’s it! It even supports up to 6 players like the original game.
It’s also possible to use a regular deck of cards, although it can be challenging to go beyond 4 players (still possible but a little “abstract”).
Cheers!
Published on Thursday 07 September 2023 17:08
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given an array of words made up of alphabets only. Write a script to find the number of pairs of similar words. Two words are similar if they consist of the same characters.
use v5.38;
use boolean;
sub is_similar{
my($s0, $s1) = @_;
my(%h0, %h1);
do { $h0{$_} = undef } for split //, $s0;
do { $h1{$_} = undef } for split //, $s1;
return false if keys %h0 != keys %h1;
do { return false if !exists $h1{$_} } for keys %h0;
return true;
}
sub similar_words_pairs_count{
my @words = @_;
my @similar;
do{
my $word_index = $_;
my @similar_temp = grep { $words[$word_index] ne $words[$_] &&
is_similar $words[$word_index], $words[$_] } $word_index + 1 .. @words - 1;
push @similar, @words[@similar_temp] if @similar_temp > 0;
} for 0 .. @words - 1;
return @similar + 0;
}
MAIN:{
say similar_words_pairs_count qw/aba aabb abcd bac aabc/;
say similar_words_pairs_count qw/aabb ab ba/;
say similar_words_pairs_count qw/nba cba dba/;
}
$ perl perl/ch-1.pl
2
3
0
The core of this problem is to count up the number of pairs of similar words. A clearly
good use of grep
, but how to do that exactly? Well, here we define a subroutine
is_similar
that returns a true/false value depending on if the words meet the definition
of similar given in the problem. That's done by expanding the words into arrays of
characters, stuffing those characters into hash key slots in order to force uniqueness,
and then seeing if the two key sets are equal.
Once we have the logic to determine similarity worked out we can then use it in grep
and
count up the results.
You are given an array of integers. Write a script to sort the given array in increasing order based on the frequency of the values. If multiple values have the same frequency then sort them in decreasing order.
use v5.38;
sub frequency_sort{
my(@numbers) = @_;
my %frequency;
do{$frequency{$_}++} for @numbers;
my $frequency_sorter = sub{
my $c = $frequency{$a} <=> $frequency{$b};
return $c unless !$c;
return $b <=> $a;
};
return sort $frequency_sorter @numbers;
}
MAIN:{
say join q/, /, frequency_sort 1, 1, 2, 2, 2, 3;
say join q/, /, frequency_sort 2, 3, 1, 3, 2;
say join q/, /, frequency_sort -1, 1, -6, 4, 5, -6, 1, 4, 1
}
$ perl perl/ch-2.pl
3, 1, 1, 2, 2, 2
1, 3, 3, 2, 2
5, -1, 4, 4, -6, -6, 1, 1, 1
This problem ended up being a bit more complex than it seemed after the first reading.
Perl makes this sort of complexity easy to manage though! sort
can take a custom sorting
subroutine as an argument. That is what is done here, with the requirements of the
frequency sort for this problem implemented within the subroutine referenced by
$frequency_sorter
. This is written as an anonymous subroutine in order to obtain a
closure around %frequency
. Finally, observe that we can use the scalar reference
directly with sort
. sort
is flexible enough to know how to use the reference.
Published on Thursday 07 September 2023 06:00
TL;DR
I discovered about
X-Unsent
.
I like automating repetitive tasks with small command-line programs because it’s fun and spares me a lot of errors, mostly in the form of things I forget. So it’s no wonder that after the thirdAHEMthirtiest email with the same shape, I thought about automating the generation of those emails too.
For reasons that I’m not willing to confeAHEMdisclose, I’m not sending those email straight away but through the Outlook client. Only fact is, when I generate an email in a valid, standards-compliant way using Perl (via module MIME::Entity, in particular), opening it with a double click makes it appear like I received it, so to actually send it I have to either reply or forward.
Yuck.
This time I decided that enough is enough and give another spin to the search wheel. Which, to be honest, seems like it’s been reset to the nineties, considering the quality of the results, or even worse, considering that there was not that much advertising at the time yet.
But I’m digressing.
This time I got lucky with this result (I can’t remember my actual query): EML files no longer opening as a draft e-mail to send.
Oh-oh! So it was at least possible in the past!
I find the first reply… curious: you can revert back. Well, that’s lateral thinking at its finest.
Sarcasm apart, the original sender was kind enough to also provide a
solution that still seems to work in the Outlook I have in Windows: set
a custom header X-Unsent
to 1
:
X-Unsent: 1
When this like appears in the email’s headers in the file, double-clicking on it opens the email in draft mode, complete with a shiny Send button.
Thanks Ralph Taylor!
Published on Wednesday 06 September 2023 06:00
Go read On Craft.
Published by perlancar on Friday 01 September 2023 01:07
dist | author | abstract | date |
---|---|---|---|
Acme-CPANModules-Sampling | PERLANCAR | List of modules to sample items from a list | 2023-08-11T00:05:10 |
Acme-MetaSyntactic-always_sunny | PERLANCAR | Characters from the sitcom It's Always Sunny In Philadephia (2005-) | 2023-08-04T00:05:29 |
Alien-CXC-param | DJERIUS | Build and Install the CIAO cxcparam library | 2023-08-17T22:33:57 |
Alien-Ruby | NHUBBARD | Alien package for the Ruby programming language | 2023-08-21T03:30:10 |
Alien-libgs1encoders | HANGY | Build and install libgs1encoders, a C-based GS1 barcode parser | 2023-08-17T21:17:02 |
Alien-parasail | CHRISARG | Install the parasail aligner shared libraries for use with (Bio)Perl. | 2023-08-25T04:22:55 |
App-FileComposer | ARIDEV | Dumps pre defined scripts! | 2023-08-14T21:45:27 |
App-HL7-Compare | BRTASTIC | compare two HL7 v2 messages against one another | 2023-08-19T06:15:50 |
App-Mkscript | ARIDEV | write scripts and files quickly! | 2023-08-11T22:03:13 |
App-Oozie | BURAK | Tooling/wrappers for Oozie job deployment and scheduling | 2023-08-31T13:55:48 |
App-SymlinkUtils | PERLANCAR | CLI utilities related to symbolic links (symlinks) | 2023-08-25T00:05:29 |
App-alluniq | TULAMILI | Align the number of columns on each line upon TSV input. | 2023-08-12T05:44:28 |
App-colalign | TULAMILI | Align the number of columns on each line upon TSV input. | 2023-08-11T15:28:59 |
App-colconnect | TULAMILI | 2023-08-10T13:56:33 | |
App-collen | TULAMILI | shows the numbers related to the numbers of the columns of each input line. | 2023-08-12T06:27:22 |
App-perlmv-scriptlet-add_extension_according_to_mime_type | PERLANCAR | Guess the file content's MIME type using File::MimeInfo::Magic then if type can be guessed and file doesn't yet have extension or has unmatching extension then add an extension | 2023-08-26T00:05:21 |
App-sdview-Output-HTML | PEVANS | generate HTML output from App::sdview | 2023-08-25T21:42:24 |
App-sdview-Output-Tickit | PEVANS | interactive terminal-based viewer for App::sdview | 2023-08-26T00:17:14 |
Apple-AppStoreConnect | DKECHAG | Apple App Store Connect API client | 2023-08-06T13:46:02 |
Authen-SASL-SCRAM | EHUELS | SCRAM-SHA-1/256/512 support for Authen::SASL | 2023-08-05T20:11:38 |
BankDetails-India | MANJREKAR | Perl interface to access the ifsc.razorpay.com webservice. | 2023-08-10T11:20:47 |
Bencher-Scenarios-Date-TimeOfDay | PERLANCAR | Scenarios to benchmark Date::TimeOfDay | 2023-08-06T00:05:56 |
Bencher-Scenarios-Digest-SHA | PERLANCAR | Scenarios to benchmark Digest::SHA | 2023-08-13T00:05:22 |
Bencher-Scenarios-File-Flock-Retry | PERLANCAR | Scenarios to benchmark File::Flock::Retry | 2023-08-20T00:05:26 |
Bencher-Scenarios-HTTP-Tiny-Patch-Retry | PERLANCAR | Benchmark HTTP::Tiny::Patch::Retry | 2023-08-27T00:06:14 |
Benchmark-DKbench | DKECHAG | Perl Benchmark | 2023-08-28T22:30:12 |
Blockchain-Ethereum-Keystore | REFECO | Ethereum keystorage utilities | 2023-08-06T23:14:42 |
CPE | GARU | Common Platform Enumeration identifiers | 2023-08-17T04:27:20 |
CXC-Form-Tiny-Plugin-OptArgs2 | DJERIUS | A Plugin to interface Form::Tiny with OptArgs2 | 2023-08-03T04:49:22 |
Chicken-Ipsum | DCHURCH | Generate random chicken noises. | 2023-08-10T20:02:58 |
DBIx-Class-Storage-DBI-MariaDB | RAGE | Storage::DBI class implementing MariaDB specifics | 2023-08-07T13:33:27 |
Dancer2-Template-Mason | YANICK | Mason wrapper for Dancer2 | 2023-08-01T17:54:04 |
Data-Pretty | JDEGUEST | Data Dump Beautifier | 2023-08-06T08:18:59 |
Dispatch-Fu | OODLER | Provides a reduction based approach to given/when or variable dispatch | 2023-08-24T05:29:04 |
Dist-Zilla-Plugin-GitHub-CreateRelease | TIMLEGGE | Create a GitHub Release | 2023-08-21T23:55:07 |
ENV-Util | GARU | parse prefixed environment variables and dotnev (.env) files into Perl | 2023-08-10T04:30:58 |
Export-These | DRCLAW | Terse Symbol (Re)Exporting | 2023-08-11T02:02:24 |
Finance-Random-Price | SKIM | Perl class for creating random price. | 2023-08-29T18:50:19 |
GS1-SyntaxEngine-FFI | HANGY | Provides a FFI wrapper for libgs1encoders | 2023-08-25T18:56:56 |
Imager-zxing | TONYC | Barcode scanning with libzxing-cpp | 2023-08-28T12:49:08 |
Import-These | DRCLAW | Terse, Prefixed and Multiple Imports with a Single Statement | 2023-08-11T03:58:17 |
Loverl | NOBUNAGA | Lover – A LÖVE2D game development command-line interface. | 2023-08-03T01:32:21 |
Magic-Check | LEONT | Add type/value checks to variables | 2023-08-26T15:21:42 |
Magic-Coerce | LEONT | magical coercers for scalar values | 2023-08-26T11:25:58 |
Mo-utils-EAN | SKIM | Mo EAN utilities. | 2023-08-27T18:31:36 |
Namespace-Subroutines | NYRDZ | Finds subroutines in namespace (attributes included). | 2023-08-19T13:48:55 |
Object-Pad-FieldAttr-Checked | PEVANS | apply type constraint checks to Object::Pad fields | 2023-08-14T15:07:01 |
Object-PadX-Log-Log4perl | WATERKIP | A logger role for Object::Pad based classes based on Log::Log4perl | 2023-08-19T02:49:18 |
Onyphe | GOMOR | ONYPHE base class | 2023-08-30T05:30:05 |
Proc-ForkSafe | SKAJI | help make objects fork safe | 2023-08-03T23:08:52 |
RT-Extension-EmailReplyDelimiter | AJWOOD | Strip text from emails after a delimiter | 2023-08-19T13:36:08 |
RT-Extension-NewTicketFromCorrespondence | AJWOOD | Make new tickets from correspondence | 2023-08-17T22:33:46 |
RT-Extension-PinComment | AJWOOD | Add a "pin comment" feature to tickets | 2023-08-19T22:42:11 |
Random-AcademicTitle-CZ | SKIM | Class for random Czech academic title. | 2023-08-21T22:25:20 |
Resource-Silo | KHEDIN | lazy declarative resource container for Perl. | 2023-08-12T21:03:44 |
Rope | LNATION | The great new Rope! | 2023-08-15T14:51:14 |
SPVM-HTTP-Minimal | KIMOTO | HTTP Client | 2023-08-22T06:32:07 |
SPVM-Mozilla-CA | KIMOTO | Mozilla's CA cert bundle in PEM format | 2023-08-30T00:26:16 |
SPVM-Net-SSLeay | KIMOTO | SPVM bindings for OpenSSL | 2023-08-31T01:33:14 |
Schedule-SGELK | LSKATZ | 2023-08-11T16:45:12 | |
SlideMap | JWHITE | Perl module for the creation of MicroArray slide maps | 2023-08-11T13:28:37 |
Statocles-Plugin-Highlight-Kamelon | VOEGELAS | Highlight code | 2023-08-09T14:29:04 |
Term-Tmux-StatusBar | FREED | change tmux status bar. | 2023-08-31T11:26:37 |
Terse-View-TT | LNATION | Terse Template Toolkit View | 2023-08-06T19:16:12 |
Test-Neo4j-Types | AJNN | Tools for testing Neo4j type modules | 2023-08-01T14:02:31 |
Types-Equal | KFLY | type constraints for single string equality | 2023-08-14T00:32:06 |
WWW-Mechanize-Chrome-DOMops | BLIAKO | Operations on the DOM | 2023-08-11T21:21:35 |
WWW-Suffit-Client | ABALAMA | The Suffit API client library | 2023-08-03T16:00:44 |
WWW-Suffit-Server | ABALAMA | The Suffit API server library | 2023-08-24T16:45:37 |
exact-fun | GRYPHON | Functions and methods with parameter lists for exact | 2023-08-19T16:59:03 |
mccs | IDOPEREL | Fully-featured static file server. | 2023-08-06T12:22:15 |
tmux-status-bar | FREED | change tmux status bar. | 2023-08-30T18:20:04 |
Number of new CPAN distributions this period: 72
Number of authors releasing new CPAN distributions this period: 44
Authors by number of new CPAN distributions this period:
No | Author | Distributions |
---|---|---|
1 | PERLANCAR | 8 |
2 | TULAMILI | 4 |
3 | PEVANS | 3 |
4 | KIMOTO | 3 |
5 | AJWOOD | 3 |
6 | SKIM | 3 |
7 | DKECHAG | 2 |
8 | HANGY | 2 |
9 | LNATION | 2 |
10 | GARU | 2 |
11 | DRCLAW | 2 |
12 | ABALAMA | 2 |
13 | LEONT | 2 |
14 | FREED | 2 |
15 | DJERIUS | 2 |
16 | ARIDEV | 2 |
17 | BRTASTIC | 1 |
18 | DCHURCH | 1 |
19 | WATERKIP | 1 |
20 | CHRISARG | 1 |
21 | BURAK | 1 |
22 | NOBUNAGA | 1 |
23 | BLIAKO | 1 |
24 | KFLY | 1 |
25 | EHUELS | 1 |
26 | TONYC | 1 |
27 | NHUBBARD | 1 |
28 | GRYPHON | 1 |
29 | RAGE | 1 |
30 | KHEDIN | 1 |
31 | NYRDZ | 1 |
32 | SKAJI | 1 |
33 | LSKATZ | 1 |
34 | OODLER | 1 |
35 | YANICK | 1 |
36 | IDOPEREL | 1 |
37 | JDEGUEST | 1 |
38 | TIMLEGGE | 1 |
39 | JWHITE | 1 |
40 | VOEGELAS | 1 |
41 | MANJREKAR | 1 |
42 | GOMOR | 1 |
43 | REFECO | 1 |
44 | AJNN | 1 |
Published by alh on Monday 28 August 2023 08:15
Tony writes:
``` [Hours] [Activity] 2023/07/03 Monday 0.92 #21181 fixes, testing, re-push and push to smoke-me 0.50 #21180 fixes, testing, push for re-CI 1.52 apply one of my PRs, look into unexpected mingw64 failure
2.94
2023/07/04 Tuesday 0.42 #21120 apply to blead, perldelta update, add to maint votes 0.65 #21132, #21095 apply to blead, perldelta #21202 comment 0.08 #21118, #21060 apply to blead 0.28 #21031 apply to blead 0.85 #21041 testing, checks to see if regen changes meant this needed updates, apply to blead 0.45 #21030 testing, apply to blead, perldelta 0.30 #21180 check CI results, apply to blead
4.40
2023/07/05 Wednesday 2.55 #21202 more testing, only happens when linking with -g, doesn’t happen with gcc from WIP strawberry perl 3.03 #21202 work on trying to use mingw64 that’s meant to be
5.58
2023/07/06 Thursday 1.65 #21202 mingw64 that’s part of the runner is old, install using action, but it’s ucrt, see if we can detect that
2.63
2023/07/10 Monday 0.68 #21212 research and comment 1.98 #21202 detect CRT type and pass it into the build, start on adapting conditional compilation to match
3.88
2023/07/11 Tuesday 1.60 #21202 clean up, work on adapting CI itself
4.80
2023/07/12 Wednesday 0.38 #21202 change as suggested by xenu, push for CI 0.08 #21202 squash UCRT re-work into original commit and re- push 0.35 #21012 comment 0.13 review github notifications 1.08 #21176 fix issues, re-push 0.43 push revert for generateuudmap change to CI 0.57 #21230 review, comment 0.20 #21227 review and approve 0.08 #21226 review and approve
3.45
2023/07/13 Thursday 1.50 #21012 follow-up, add a related fix, comment 0.10 generate_uudmap revert: make PR 21237 0.80 #21233 work on fix and testing, make into a branch on the upstream and push for CI 0.13 #21233 clean up and make pr pjf/autodie#120 0.12 #21152 briefly comment 2.15 #21186 research, testing and comment 0.73 #21084 work on fixing format strings, side-tracked by
5.53
2023/07/17 Monday 0.13 #21240 comment 0.82 #21241 review and comments 2.40 #21186 have porting tests handle CRLF checkouts on Win32,
3.35
2023/07/18 Tuesday 0.35 #21230 comments 0.35 #21240 review updates and approve 0.17 #21252 research and comment 0.48 #21186 re-work, testing 0.32 #21186 recheck, push for CI 0.12 #21257 review and comment
2.52
2023/07/19 Wednesday 0.08 #21257 comment about possible mis-close 0.18 #21241 follow-up 0.17 #21256 research 0.43 #21256 follow-up comment, separate comment on another commit 0.23 #21266 review and approve
1.21
2023/07/20 Thursday 0.45 github notifications 0.92 #21265 review, research and approve 1.47 #20811 rebase, testing, re-check 0.13 #21152 apply to blead
3.40
2023/07/24 Monday 0.48 #21256 review new changes and approve 0.45 #21230 follow-up 0.38 PPC#36 review, re-check mailing list discussion 1.08 #21271 debug and work on a fix, testing, make PR 21284
3.56
2023/07/25 Tuesday 0.65 #21271 apply to blead, add to votes files, perldelta 0.68 ppc#36 comment 0.05 #21287 review and approve 0.03 #21281 review and apply to blead 0.17 #21280 review, briefly research and comment 0.07 #21280 review changes, follow-up comment 1.75 #21286 review and approve 0.43 #21149 re-check and apply to blead
3.86
2023/07/26 Wednesday 0.18 ppc#36 comment 0.80 #21290 research, comment 0.08 #21289 comment briefly 0.18 #21275 close 0.08 #21292 review and approve 0.05 #21285 review and approve 1.20 #21294 reviewing more locale changes 0.43 #21294 more reviewing more locale changes 0.10 #21211 review and approve 0.22 #21236 review and approve 0.18 #21012 rebase to get the mingw fix 0.18 #21187 work on a doc fix 1.40 try -Wshadow, work on -Wconversion fixes (since it detects
5.08
2023/07/27 Thursday 0.60 #21294 research, follow-up 0.77 more -Wconversion 0.50 #21187 make the doc update more complete, make PR 21298 0.95 #21297 testing, comment 0.70 #21012 apply to blead and perldelta 0.65 #20990 rebase and testing
4.79
2023/07/31 Monday 0.40 #21297 review new patch and approve 0.33 #21294 review changes and approve 0.20 #21298 minor update 0.60 #21310 review, testing (and find -Dusequadmath -Dclang doesn’t work with or without this change), approve 0.07 #21302 review and approve 0.15 #21304 research 0.37 #20811 rebase and apply to blead 0.48 look at some win32/gnumakefile optimization fixes 0.32 #21312 review and approve 1.07 more win32/gnumakefile, testing 0.07 #21298 apply to blead
4.18
Which I calculate is 65.16 hours.
Approximately 54 tickets were reviewed or worked on, and 15 patches were applied. ```
Published on Saturday 26 August 2023 06:00
TL;DR
I wonder about the state of PerlMagick.
PerlMagick represents the Perl bindings for… well, it’s complicated:
Both projects include the bindings, which eventually result in the
installation of Image::Magick
and Graphics::Magick
respectively.
Out of curiosity, I tried to compile both modules for a fairly recent version of Perl (v5.36). With… frustrating results.
First of all, there’s no way to install them from CPAN. It’s the
other way around: we compile the main thing, and the modules are
available (and installable) as a side effect. A sort of Alien, but
in reverse. This has its drawbacks, because tools like carton
and
cpanm
are out of the game.
ImageMagick complains a lot. Many errors have to do with input/output, so it might be related to some library that I forgot to include during configuration/compilation.
t/blob.t .......... ok
t/bzlib/read.t .... Failed 2/2 subtests
t/bzlib/write.t ... Failed 1/1 subtests
t/composite.t ..... Failed 1/18 subtests
t/filter.t ........ Failed 1/58 subtests
t/getattribute.t .. ok
t/jng/read.t ...... ok
t/jng/write.t ..... ok
t/jpeg/read.t ..... ok
t/jpeg/write.t .... ok
t/montage.t ....... ok
t/ping.t .......... ok
t/png/read-16.t ... ok
t/png/read.t ...... ok
t/png/write-16.t .. ok
t/png/write.t ..... ok
t/read.t .......... 1/47 Readimage (gradient:red-blue):
Exception 395: UnableToOpenConfigureFile `colors.xml'
@ warning/configure.c/GetConfigureOptions/722
at t/subroutines.pl line 317.
t/read.t .......... Failed 1/47 subtests
t/setattribute.t .. ok
t/tiff/read.t ..... ok
t/tiff/write.t .... ok
t/write.t ......... Failed 1/32 subtests
t/zlib/read.t ..... Failed 1/2 subtests
t/zlib/write.t .... Failed 1/1 subtests
GraphicsMagick complains too:
t/blob.t .......... ok
t/composite.t ..... ok
t/filter.t ........ ok
t/getattribute.t .. ok
t/jbig/read.t ..... ok
t/jbig/write.t .... ok
t/jng/read.t ...... ok
t/jng/write.t ..... ok
t/jpeg/read.t ..... ok
t/jpeg/write.t .... ok
t/montage.t ....... Failed 19/19 subtests
t/ping.t .......... ok
t/png/read-16.t ... ok
t/png/read.t ...... ok
t/png/write-16.t .. ok
t/png/write.t ..... ok
t/ps/read.t ....... ok
t/ps/write.t ...... ok
t/read.t .......... ok
t/setattribute.t .. ok
t/tiff/read.t ..... ok
t/tiff/write.t .... ok
t/ttf/read.t ...... ok
t/write.t ......... 1/? SetImageAttribute:
Extending attribute value text is deprecated!
(key="comment")
SetImageAttribute: Extending attribute value text
is deprecated! (key="comment")
t/write.t ......... ok
t/zlib/read.t ..... ok
t/zlib/write.t .... ok
Anyway, this seems to be a bug introduced in the very latest release (as of now, of course), properly tracked in a bug report.
Cheers!