Published by user2854259 on Tuesday 19 March 2024 07:55
I have a perl script to import Files as and when available, and if files are not available, it goes to sleep. The files are kept in a remote system. Layout of the code is as:
while(1)
{
\\"Searching if Files Available for $date_yymmdd......"
if (not -e $file)
{ \\ sleep }
else
{
\\if file is not imported yet, then Import
\\else sleep
}
}
So I intend this code be on infinite loop executing import duty as and when files are available.
So here is the thing. If I execute this code today, it does check if files are available and import as intended and then goes to sleep.
But then on next day, it does periodically check for files availability, but even if they are made available, the if condition (if (-e $file)) fails and script fails to realise that file is present.
Finally, if i terminate the script and re-run, then it again correctly identifies and imports file as intended without any change in script.
Why is it that i have to re run the script. Why does it fail in the if (-e $file) condition is what i dont get.
Published by vam on Tuesday 19 March 2024 03:32
I am trying to run perl one liner to get the string from a header file "elf.h" which has following lines :-
#define ELFOSABIV_STDELF_V1 8U // STD ELF ABI
#define ELFOSABIV_PRE_STDELF 7U // latest abi version
#define ELFOSABIV_LATEST 6U // latest abi version
I am trying to get ELFOSABIV_LATEST
version which is 6U
. Actually i need to feed this output to executable file. So i have to go with perl one liner to make it simple.
Output :-
In Linux:-
perl -ne "print $1 if /#define\s+ELFOSABIV_LATEST\s+(\S+)/" /home/test/elf/elf.h
#define ELFOSABIV_LATEST 6U // latest abi version
In Windows:-
perl -ne "print $1 if /#define\s+ELFOSABIV_LATEST\s+(\S+)/" /home/test/elf/elf.h
6U
Why is the difference in output among windows and linux above? Do i need to set something before printing. I need to make sure that output has to be 6U
for both windows and linux.
Published by David G. on Tuesday 19 March 2024 03:16
I'm trying to practice pulling salary information from openpayroll.com. I need to be able to analyze the links on a given page and click on them if need be. When I run the following
mech-dump --all https://openpayrolls.com/other/utah-carbon-county-housing-authority
It only returns information regarding the headers but the links part is empty, i.e. it returns --> Links:
and that's it. The page, however, is full of links. Do I need to pass an additional option to access all the links on the webpage?
I have inherited some perl scripts that I've generally been able to edit well enough with my knowledge from other languages, but I need to make a change that has me stumped.
The user wants the output that happens from this loop to be reversed.
for ($nn=0;$nn<=$range_max;$nn++) { my $range=sprintf("%02d",$nn); $sum_of_A += $A_EACH_RANGE{"$range"}; $sum_of_B += $B_EACH_RANGE{"$range"}; printf("\"\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", $scale[$nn], commify($A_EACH_RANGE{"$range"}), commify($B_EACH_RANGE{"$range"}), commify($sum_of_A), commify($sum_of_B)); }
So I figured all I had to do was start the for loop at the end like this:
for ($nn=$range_max;$nn>=0;$nn--) {
Then I realized there's some cumulative math going on in the loop, which means the sum of everything needs to be at the top now instead of the bottom.
Now I'm stuck, I've made a few attempts like pushing it into an array so I could have the option to output in forward or reverse, but all my attempts just hang with no warnings or errors.
I figure there's a more elegant solution but my Google-fu hasn't helped.
Published by mauke on Monday 18 March 2024 18:43
perldelta for ed37371b34c7f (Tie::File)
Published by vvch on Monday 18 March 2024 17:25
My boss believes that perl program without explicit exit(0)
at the end may return some other value, e. g. that one returned by the last function call in the program, or may be last system call. Perhaps he confuses it with bash.
So he requires his programmers to put explicit exit(0)
statement at the end of each perl script.
Simple code examples or references to existing programs cannot convince him.
Unfortunately I have no idea how to find the relevant topic in the documentation quickly: all keywords are too common.
May be someone can point out exact place in the perl documentation what is the perl program exit code when the program just reaches its end, without any die
or exit
. (Yes, in fact I know what it is, but I need an official confirmation).
Published by U. Windl on Monday 18 March 2024 10:52
Note that I had set "equality" in double-quotes, so read on about the details:
I wrote some code that stores Perl objects in a file and retrieves them from there. I'm using my own JSON-based code using text representation to be independent from Perl. When I wrote a self-test checking whether the loaded object is the same as the stored object, I got a surprise:
DB<14> x $self->time() == $other->time()
0 ''
DB<15> x $self->time()
0 4842276.32536854
DB<16> x $other->time()
0 4842276.32536854
DB<17> x $self->time() == $other->time()
0 ''
DB<18> x $self->time() - $other->time()
0 '-2.79396772384644e-09'
So while the numbers output look identical, their internal representation is not. However when I create a JSON representation for both, there is no difference (different numbers this time (as time went on); also note that the order of the fields varies as it's a Perl HASH):
DB<1> x $self->flat
0 '{"time":4842854.29538268,"crc":23407,"use_counter":19}'
DB<2> x $other->flat
0 '{"use_counter":19,"crc":23407,"time":4842854.29538268}'
(The real objects are more complex, but this shows the principle; the time value comes from clock_gettime(CLOCK_MONOTONIC) # useTime::HiRes qw(clock_gettime CLOCK_MONOTONIC)
)
Now I wonder: Should I simply try to compare the numbers as strings (as a work-around), or should I use an elaborate ("correct") solution like https://stackoverflow.com/a/33024979/6607497?
Randal Schwartz is guest on Flosss Weekly 765, mostly for Dart, but he also talks quite a bit about Perl.
One of the interesting management of Dart is that they have people assigned to work shifts to triage and respond to issues so that requestors can get immediate feedback that at least someone saw their issue. I'll let him tell the rest of the story, but it's a good one.
Published by iabyn on Monday 18 March 2024 07:54
Perl_tied_method(): *conditionally* use RC stack Fixes GH #21784. Perl_tied_method() is used to call tied methods for filehandles. One of its actions is to push a new stackinfo (and hence a new argument stack) to run the method under. When the method returns, any returned values are copied back to to original stack and the stackinfo popped. But stackinfos (and the AV pointed to by si_stack) aren't freed at that point; they are kept around until global destruction, in case they're needed again. Before this commit, Perl_tied_method() was incorrectly *always* making the new stack AvREAL: this should in fact be done only on PERL_RC_STACK builds. The effect of this was that, on non-PERL_RC_STACK builds, any temp SVs created as the return value(s) from the method call, would be left on the abandoned stack, while the SVs themselves have long since been freed. Normally this doesn't matter much - the array will be finally emptied only during global destruction, which doesn't care if an already-freed SV is attempted to be freed again. But this was causing Coro to fail, because it maintains a stackinfo chain per green thread, and manages and frees them itself, so they can end up being freed before global destruction, triggering an 'Attempt to free unreferenced scalar' warning. For completeness, this commit now also resets PL_stack_sp to PL_stack_base before abandoning the stack, so that that on PERL_RC_STACK builds, there's no chance of the copied return value SVs being double-counted later on,
Published by Gabor Szabo on Monday 18 March 2024 05:43
Originally published at Perl Weekly 660
Hi there,
Happy Ramadan to all the readers who fast during this holy month. May ALLAH s.w.t accept your fasting, Ameen.
I recently became active on official Slack for The Perl Foundation after a long gap. I noticed it is very much active and live. Lots of positive noise and useful information shared with each other. I am not a big fan of Slack but after spending just few days, I find it easy to move around. I would like to keep an eye for important news and announcement. Earlier my only source of information was the good old https://blogs.perl.org. We used to have regular post by Perl enthusiasts but that has stopped unfortunately. And I don't blame them as I also stopped blogging completely. As and when I do blog, I use The Weekly Challenge platform. Having said, the platform is still used by some, for example Perl Steering Council for weekly updates. Every now and then, you do get some magical post by Perl fans. One such post, Changes in MooX::Role::Parameterized appeared last week by E. Choroba. I have been a big fan of Moo - Minimalist Object Orientation, so this post became even more important for me. Although, Corinna has made it to the Perl core, it is still a long way before it becomes a complete solution to all OO needs. I am looking forward to the next big release which would bring in some more features, hopefully.
What's new on CPAN?
I was introduced to perl.com by the post series What's new on CPAN? by David Farrell. It used to be regular every month with full of fun facts about new CPAN modules released. During those days, I used to be active on CPAN and released few CPAN. I had the honour to find place in the post often. Recently Olaf Alders took the initiative to revive the activities on perl.com. Because of his hard work and with the help of Mathew Korica we now have the post series back. You must check latest in the series, What's new on CPAN - February 2024.
I just realised that this is my 150th edition and in 2 months I will complete 6 years as co-editor of the Perl Weekly newsletter. It has been a very fruitful learning experience for me and I enjoyed it thoroughly.
Keep the spirit high and don't let the bad influence pull you down. Please do take care your health and loved ones.
--
Your editor: Mohammad Sajid Anwar.
Time has come to start preparing for the next big event. Please reserve your place as soon as you can.
Teaming with the french mongers, Open Food Facts organize a Hackathon around the use of Perl by it's web server which is the heart of the project. It will take place in Paris, on Saturday March 23 and Sunday March 24. Remote participation is possible.
It is so pleasing to see my favourite series is back. Thank you the entire team behind this, you guys are doing a great service to keep this alive.
Another week another update by the super charged Perl Steering Council.
For all Moo users, this is for you if you have worked with Roles. This change would make your life easy. Enjoy !!
Perl API client for Intellexer by Joshua Day, his first contribution to CPAN and hope not the last.
Grant report for the work carried out by Tony Cook.
The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from all of the contributors during the month.
Welcome to a new week with a couple of fun tasks: "Element Digit Sum" and "Multiply by Two". If you are new to the weekly challenge, why not join us and have fun every week? For more information, please read the FAQ.
Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Unique Occurrences" and "Dictionary Rank" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Adam's use of do { ... } for .. always fascinates me. Mind you this is happening alongside the latest Perl v5.38.
Solution to dictionary rank blown me away. You must checkout his creative innovation.
As always Raku is showing off with the help powerful feature of Bag. Keep it up great work.
Have you played with BQN? If not then you should as it is not just another programming language. Check out the post yourself.
Task analysis by Dace is unmatched. I just simply love the way he deals with challenge. Keep it up.
Raku is presenting mathod chaining once again. It is one of my favourite. How about you?
Explore the mathematical view of the dictionay rank task. You may find it too complex but it is always fun.
Raku one-liner is showing the elegance. Raku Rocks !!
Using CPAN and still getting one-liner in Perl, incredible. Keep us entertained every week.
We have seen how CPAN cam be handy is dealing with challenges. This week too, we saw the evidence.
I see Raku code written in Perl style. It tells Packy is a diehard Perl fan. Thank you for your contributions.
Just a simple and straight forward approach, anyone can easily follow. Well done and keep it up.
For permuation related challenge, Math::Combinatorics is one of the choices CPAN provides. See the post how this solved the task.
Unlike others Roger used Set of Raku language to deal with the challenge this week. In addition we got PostScript solution discussed too. Highly recommended.
Python is my new crush and everytime I read post about Python solution, it feels nice to be able to follow through. The use of defaultdic is one of them. Thanks for sharing.
Great CPAN modules released last week;
MetaCPAN weekly report;
StackOverflow Perl report.
You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.
Want to see more? See the archives of all the issues.
Not yet subscribed to the newsletter? Join us free of charge!
(C) Copyright Gabor Szabo
The articles are copyright the respective authors.
Published by tonycoz on Monday 18 March 2024 02:31
testsuite.yml: fix ASAN build tests This works around actions/runner-images#9491 Apparently a recent Ubuntu update changed the ASLR entropy to use more bits which is incompatible with ASAN as shipped with Ubuntu. This adjusts the entropy bits to be compatible with ASAN. Thanks to ilmari who found the ticket linked above.
Published by E. Choroba on Sunday 17 March 2024 20:10
If you’ve never worked with MooX::Role::Parameterized or MooseX::Role::Parameterized, you might wonder what is a parameterized role at all?
Roles are used when you need to share behaviour among several classes that don’t have to be related by inheritance. Normally, a role just adds a bunch of methods to the class that consumes it (there’s more, you can for example specify which other methods the role expects to already exist).
A parameterized role makes it possible to provide parameters for the consumed role. This way, you can adjust the behaviour for each consuming class.
The standard syntax to apply a role to a class before version 0.100 of the module was to use the apply
class method:
# My/Role.pm
package My::Role;
use Moo::Role;
use MooX::Role::Parameterized;
role {
my ($params, $mop) = @_;
$mop->has($params->{name} => is => $params->{is});
}
# My/Obj.pm
package My::Obj;
use Moo;
use My::Role;
'My::Role'->apply({
name => 'size',
is => 'ro',
});
If we now created an object $o
using my $o = 'My::Obj'->new(size => 2)
, we could get the value of the attribute size
using the $o->size
getter: the role created a new read-only attribute size
for us.
What I didn’t like about applying a role to a class the old standard way was it wasn’t declarative. You could easily overlook it as a block of code happening at runtime, while the meaning of the code was This is how a role is consumed. Therefore, I used the alternative experimental syntax:
package My::Obj;
use Moo;
use MooX::Role::Parameterized::With 'My::Role' => {
name => 'size',
is => 'ro',
};
It's part of a use
clause, so it’s clear that it’s happening at compile time.
I promoted one of my side-jobs to a full-time job recently. They gave me a new computer where I had to install all my code base to start working on it 8 hours a day instead of a couple a month.
Imagine my surprise when the code stopped with an error:
Can't locate object method "size" via package "My::Obj" at ./run.pl line 37.
Line 37 was where I called $o->size
!
When installing the dependencies for my code, the most recent version of MooX::Role::Parameterized
was installed from CPAN (0.501). The experimental syntax is no longer documented and as I found out, doesn’t work anymore.
The old non-experimental syntax still works, but there’s a new syntax, too. It uses the with
keyword that looks like the one that can be used to consume a Moo::Role, but if we first use MooX::Role::Parameterized::With
, it can also accept parameters for the role application.
package My::Obj;
use Moo;
use MooX::Role::Parameterized::With;
with 'My::Role' => {
name => 'size',
is => 'ro',
};
Moreover, we should change the definition of the role, too. Parameters should be predeclared using the parameter
keyword (similarly to MooseX::Role::Parameterized), and they can be then accessed via getters instead of peeking inside a parameter hash reference.
package My::Role;
use Moo::Role;
use MooX::Role::Parameterized;
parameter name => (is => 'ro');
parameter is => (is => 'ro');
role {
my ($params, $mop) = @_;
$mop->has($params->name => is => $params->is);
}
Published by /u/de_sonnaz on Sunday 17 March 2024 17:05
Hi,
I am using Template::Mustache in a prooted Debian in termux on Android.
It works fine, however it produces this annoying warning:
"Flock not available: 'Function not implemented': continuing in unsafe mode".
As far as I can see it ultimately comes from Path::Tiny when slurping a file.
I have tried to get rid of it with "no warnings" but that did not do the trick.
So how can I suppress this warning?
Published by /u/niceperl on Sunday 17 March 2024 08:30
Published by Unknown on Sunday 17 March 2024 09:30
Published by Unknown on Sunday 17 March 2024 09:27
This is the weekly favourites list of CPAN distributions. Votes count: 33
Week's winners (+3): Spreadsheet::ParseExcel
Build date: 2024/03/17 08:26:48 GMT
Clicked for first time:
Increasing its reputation:
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2024-03-17 08:25:15 GMT
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, @ints
.
Write a script to return 1
if the number of occurrences of each value in the given array is unique or 0
otherwise.
For this task I start by calculating the frequency of each integer, and store this in a dict (hash in Perl) called freq
.
def uniq_occurrences(ints: list) -> bool:
freq = defaultdict(int)
for i in ints:
freq[i] += 1
I then loop through the values of the dict (the frequency). If I have seen this frequency before, we know it is not unique, and can return False. If I haven't seen it, I add it to the seen
dict in case we see it again.
Once I have looped through all values, I return True to indicate the occurrences are unique.
seen = {}
for i in freq.values():
if i in seen:
return False
seen[i] = 1
The second part definitely fails under TMTOWTDI. One possible alternate solution is len(freq) == len(set(freq.values())
. While probably quicker, it's not as straight forward to understand.
$ ./ch-1.py 1 2 2 1 1 3
1
$ ./ch-1.py 1 2 3
0
$ ./ch-1.py -2 0 1 -2 1 1 0 1 -2 9
1
You are given a word, $word
.
Write a script to compute the dictionary rank of the given word.
This task was a little more challenging than a first thought, and more so for the Perl solution. This is because while I can calculate all the permutations of letters easily, I only want to count unique permutations. For example, the word baa
has 3! (6) permutations, but only 3 are unique (aab
, aba
, baa
).
Thankfully there is a distinct_permutations method in more_itertools that makes this easy.
The first thing I do is convert the word into lower case and convert it into a tuple. I store this as the variable tuple_word
.
I then sort the tuple alphabetically and store this as letters
and parse it to the distinct_permutations
generator. I keep counting until I find the tuple that has the original word.
def dictionary_rank(word: str) -> int:
tuple_word = tuple(word.lower())
letters = sorted(tuple_word)
count = 0
for perm in distinct_permutations(letters):
count += 1
if perm == tuple_word:
break
return count
It should be noted that the performance of the solutions are really only good if it appears early (alphabetically) or has less than 11 characters. Calculating the rank of 'kjihgfedcba' took 35 seconds on my PC. For the record it is ranked 39,916,800th which is also 11!.
The Perl solution is slightly different. My go to for permutations in Perl is usually Algorithm::Combinatorics, but this doesn't have a function for distinct permutations. Math::Combinatorics does, however the order of them is not guaranteed.
For the task, I count all unique permutations that are less than or equal to the word, and print that.
$ ./ch-2.py CAT
3
$ ./ch-2.py GOOGLE
88
$ ./ch-2.py SECRET
255
Published on Saturday 16 March 2024 20:39
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given an array of integers, @ints. Write a script to return 1 if the number of occurrences of each value in the given array is unique or 0 otherwise.
The complete solution is contained in one file that has a simple structure.
For this problem we do not need to include very much. We’re specifying to use the current version of Perl, for all the latest features. We’re also using the boolean module, for the convenience of returning and displaying the return values.
This fragment is also used in Part 2.
Here we have a single function which does essentially all the work. First we loop through the array of numbers and count occurrences. Then the counts are themselves used as hash keys to eliminate duplicates. If no duplicates are removed then the number of these new keys is equal to the number of original count values.
sub unique_occurrences{
my %occurrences;
do{
$occurrences{$_}++;
} for
@_;
my %h;
do{$h{$_} = undef} for values %occurrences;
return boolean(values %occurrences == keys %h);
}
◇
Fragment referenced in 1.
Finally, we have a few lines of code for running some tests.
MAIN:{
say unique_occurrences 1, 2, 2, 1, 1, 3;
say unique_occurrences 1, 2, 3;
say unique_occurrences -2, 0, 1, -2, 1, 1, 0, 1, -2, 9;
}
◇
Fragment referenced in 1.
$ perl perl/ch-1.pl 1 0 1
You are given a word, $word. Write a script to compute the dictionary rank of the given word.
The solution to the second part of this week’s challenge is a little more complex than the first part. In the solution file we define our own function for computing all permutations of an array, which is then used to determine the dictionary rank.
This function is a recursive implementation of Heap’s algorithm. A lot has been written on this algorithm, so I won’t go into much detail here.
sub permutations{
my($a, $k, $permutations) =
@_;
if($k == 1){
push
@{$permutations}, [
@{$a}];
return true;
}
else{
permutations($a, $k - 1, $permutations);
for my $i (0 .. $k - 2){
if($k & 1){
($a->[0], $a->[$k - 1]) = ($a->[$k - 1], $a->[0]);
}
else{
($a->[$i], $a->[$k - 1]) = ($a->[$k - 1], $a->[$i]);
}
permutations($a, $k - 1, $permutations);
}
}
}
◇
Fragment referenced in 5.
Now that we have a way to compute all permutations we will use that to determine the dictionary rank. There is a trick here. Keep in mind that dictionaries do not have multiple entries for repeated words! In the case of words with repeated letters than there will be permutations that are effectively equal in that they contain the same letters. Although they are created by permuting equal (but different) letters for ranking purposes we will consider them the same.
sub dictionary_rank{
my($word) =
@_;
my $permutations = [];
permutations [split //, $word], length($word), $permutations;
my %h;
do {$h{join q//,
@{$_}} = undef} for
@{$permutations};
my
@permutations = sort {$a cmp $b} keys %h;
return (
grep {$permutations[$_] eq $word} 0 ..
@permutations - 1
)[0] + 1;
}
◇
Fragment referenced in 5.
MAIN:{
say dictionary_rank q/CAT/;
say dictionary_rank q/GOOGLE/;
say dictionary_rank q/SECRET/;
}
◇
Fragment referenced in 5.
$ perl ch-2.pl 3 88 255
Published by Perl Steering Council on Saturday 16 March 2024 20:58
This week, we discussed:
Published by Todd Rinaldo on Friday 15 March 2024 23:13
The Perl and Raku Conference (formerly knwn as YAPC::NA) is going strong! This year, we are celebrating 25 years, our silver anniversary, in the Silver State, Nevada! The main conference will be in Las Vegas on June 25-27, but there will be hackathons and possibly classes on the day before and the day after the conference (June 24th and 28th), so please consider joining us for the whole week!
The backbone of this conference has always been our tracks of "traditional" talks by community members and what we have come to call the "Hallway Track" the informal exchange of ideas and camaraderie that sparks new projects and fuels collaboration.
This year, we are pleased also to host the presentation of Papers and Posters accepted by the Science Perl Journal!
Registration is open, so your ticket can now be purchased.
Talk submissions are still open, and we are seeking proposals on a wide variety of subjects. This includes language features, personal projects, applications like Koha, and anything that may be of general interest to Perl and Raku programmers. (We had juggling and origami in the past. Fun!) * Talks can be 20 minutes or 50 minutes. Please submit through PaperCall. * Papers and Posters follow the guidelines of the Science Perl Journal. Links to both are also on https://tprc.us.
Speakers who are approved for a talk, paper, or poster will receive a free ticket to the event. The submission deadline is April 5th at 8pm EST, so please send us your submissions soon!
We are planning some special activities during the conference to celebrate our rich 25-year history.
Go now to https://tprc.us/ to check out what is planned and to book a room (see link to Alexis Park Resort under "Location"). Rooms start at only $75 per night, so it’s worth booking early!
The best way to register for the conference is at https://tprc2024.sched.com/tickets
Thanks, TPRC Admins
Published by Boyd Duffee on Friday 15 March 2024 08:31
I saw Jennifer's post about re-writing her perl scripts in python and how she saw a 2.5 times improvement.
How could this be? My favourite language can't be that slow.
It must be programmer error.
I have an interest in Perl and Science, so time to roll up sleeves and learn me some profiling/benchmarking. What follows is my internal monologue and the notes I scribbled down during the learning process. For those that want to follow along, I've created a small repo.
Voltaire said that Hell is other people's code. My first step was to re-write it into Modern Perl and in the process, understand what each line does. When it's written idiomatically, it's easier to refactor and I should be able to make some minor performance improvements along the way.
Assume that the original script has been tested enough. For me to be correct, I've got to produce the exact same output. I got close, except for the header line.
line 99 print OUT "\t$prefix_$j";
becomes
line 89 print $out_fh "\t$j";
Yes, that's a bug because $prefix_
doesn't exist.
Search "benchmarking tools for linux" and decide that hyperfine is good for what I'm doing. Run Jennifer's new python script against my refactored perl and find that the python is 1.26 times faster for k=3 and 1.47 times faster for k=4. For the Covid-19 sequence, these are both on the order of hundreds of milliseconds.
hyperfine --warmup 3 'perl/get_kmer_frequencies.pl Covid-19_seq.fasta 3 boyd1' 'python/get_kmer_frequencies.py -i Covid-19_seq.fasta -k 3 -p boyd2'
Ok, not bad. Better than 2.9 times faster, but that's probably down to the way that hyperfine warms the cache and separates out User time from System time.
Oh, I should just check how much I improved when I refactored. Run it against Jennifer's original perl script and ... hers was 1.1 times faster. Well, that was a bit embarrassing.
ahem I was ... aiming at improving readability, .. maintainability, y'know best practice and all that. That's my story and I'm sticking to it. ;)
Check that the output of the new file is the same as the original, otherwise you've messed up the refactoring. I started using this test script with prove to make it quick and easy.
Saved as i.t, I run it with prove i.t
for the lols.
It gets noisy when there's a problem, so I go back to running it by hand.
use Test2::V0;
my $standard = 'get_kmer_frequencies.pl';
my @files = sort { -M $a <=> -M $b } glob 'get_kmer*';
ok my $latest = shift @files;
isnt $latest, $standard, 'Files to compare';
my @args = qw'Covid-19.fasta 3';
ok system('perl', $standard, @args, 'A') == 0, 'Make A_kmers.txt';
ok system('perl', $latest, @args, 'B') == 0, 'Make B_kmers.txt';
is `diff A_kmers.txt B_kmers.txt`, q{}, 'No differences in output';
done_testing();
Clever people do this from the start.
I did this after a bug I introduced messed up the output and I hadn't immediately noticed. What it was is that I changed the key separator to a character that was found in some of those keys and it then split those keys. Oops.
When you get serious about optimizing programs, trying to enhance performance, you reach for profiling tools that can analyze your code's memory or time complexity. In Perl, Devel::NYTProf comes highly recommended. I use it to collect data on the number of times each statement is called and how long it spends executing it. That way I can work out where to invest the effort making the script faster, what gives the most bang for the buck.
Grab the profiler and run
perl -d:NYTProf get_kmer_frequencies.pl Covid-19_seq.fasta 3 boyd1
and open up the nytprof/index.html using nytprofhtml --open
to see
Calls P F Exclusive Time Inclusive Time Subroutine
9653 1 1 31.6ms 31.6ms main::rc_seq
25 2 1 28.1ms 59.7ms main::process_it
82498 7 1 9.46ms 9.46ms main::CORE:print (opcode)
3175 4 1 7.89ms 7.89ms main::CORE:sort (opcode)
Obviously, the rc_seq
is the big sub that needs attention, but what about that sort
? Quickly looking at the sort on Line 78 for my $i (keys %knucs)
I see that there's no reason to sort those keys. Saved one sort and the script runs about the same. There's another sort inside a loop which can be extracted out of the loop. Extracting that made it run 1.15 times faster!
Changing the header line (line 87) from a for loop to a join over a list is 1 or 2 percent faster.
Messing about with printing in the inner loop didn't gain much, but changing the key separator from a tab "\t"
(interpolated string) to an underscore '_'
(a string literal) made a 10% improvement. (it also introduced the bug noted above because the keys used the underscore. changed it to a colon - bug gone)
say
is marginally slower than print
so use print inside the loop that gets called a lot to save maybe 10% on that call. From 32ms to 28ms is a small, but nice gain for a one line change.
The rc_seq
sub is an if-elsif block that splits a string into individual characters, translates ACGT into their complement (TGCA), reverses the array and joins it back into a string.
Being Perl, we can manipulate and reverse the string in-place. The change makes it shorter and more obvious (sometimes it runs faster). Actually, I ran this through the profiler and the sub now runs 5 times faster.
This sub does the work of splitting the sequence into kmers and counting them. The longest time spent here is incrementing the %knucs
hash.
The second longest time is spent turning the sequence into an array of letters to create all the kmer substrings. Splitting isn't bad, but joining sets of letters together is. Use the string function, substr
instead and speed that line up by 5 times.
Now marginally faster the python script in speed. Over 20% faster for k=3, and 5% (+/- 5%) faster for k=4. That's a decent improvement.
my @items = map { my $key = join ':', $_, $i; $knucs{$key} // 0 } @record_keys;
The script spends most of its time (55ms!!!), longer than anything else, on this line.
Assume that the problem isn't the map
but constructing the key for the lookup. Change the key to a 2 dimensional lookup and see if that improves things.
WHEN you finally get it right (and remember the correct order that you construct the keys in), line 92 is now 2.5 times faster than before and the perl script is now 40% faster than the python script.
Keys are constructed/used on lines 79, 91, 135
Know when to stop.
There are no more obvious or easy gains here. Any more work is likely to yield small returns. Go outside, have a life or at the least consult the relevant chart.
Well, after thinking a while, maybe constructing the output could be improved, but I'm moving on. I've exceeded my goal of making the perl script as fast as the python script and learned more about refactoring and profiling. A bit like how audiophiles use your music to listen to their equipment, I've used Jennifer's science to better understand my Perl and had fun doing it.
There's a niggling thought at the back of my mind, now that I feel I better understand the purpose of the script, whether BioPerl can do this even faster. I will leave that for another day. Oh, look glycine has already done most of the hard work for me. Many thanks!
In summary, these are reflections on the changes that I made in chronological order. This may be someone's first time considering performance, so I include basic rules of thumb I used along with the things I did not know before.
sort
when order is not importantjoin
instead of for
)say
is slightly slower than print
. Avoid it in heavy loops.substr
is faster than split
ing and join
ingThe Human Genome is way too large. Grab the protein sequence for Caenorhabditis elegans. It takes about 5 minutes to run.
Run your frequent tests with the Covid-19 sequence. Repeated runs with anything larger take too long for rapid turnaround.
WARNING: hyperfine will run each program 20 to 40 times to get decent statistics. You won't want to wait around for a file that takes 5 minutes to process a single run.
I'll leave you with a couple of related references for further reading, chrisarg's work on parsing FastQ files fast
and a marketsplash tutorial on Perl code profiling tools
My corollary to Cunningham's Law:
Don't ask people how to make your code run faster;
Tell them their language is slow
It's taken a lot longer to reply Jennifer's post than I'd anticipated, but right now I have the warm glow that comes from being able to say, (until someone iterates on the above corollary)
... Python is SLOW!
Welcome to “What’s new on CPAN”, a curated look at last month’s new CPAN uploads for your reading and programming pleasure. Enjoy!
autodoc.pl: fix typos AUTHORs update
Published by khwilliamson on Thursday 14 March 2024 03:13
Note that __VA_OPT__ is now standardized whereas before we said it had never been standardized
Published by Yuki Kimoto - SPVM Author on Wednesday 13 March 2024 02:18
Google recently started offering a Perl API for advertising from 2020.
Published by Spontaneous21 on Tuesday 12 March 2024 10:34
Perl, a high-level, interpreted programming language, has been a stalwart in the world of computer science since its inception in the late…
Published by alh on Monday 11 March 2024 08:10
Tony writes:
``` [Hours] [Activity] 2023/12/04 Monday 0.42 #21677 minor fix. testing 0.23 #21661 check smoke results, minor commit message edit, make PR 21683 1.90 #21680 testing, debugging 1.28 #21680 fixes, testing, push for CI 1.42 #21651 testing and reproduce, try a fix and testing, push
5.25
2023/12/05 Tuesday 0.30 #21677 research 0.95 #21664 apply to blead, perldelta, comment on original perlmonks post 0.82 #13814 research 0.38 #13814 try a different approach
3.07
2023/12/06 Wednesday 1.07 #13814 review CI results, documentation, testing, make PR 21693 2.48 #21692 review, comments, try to work out getlines() cleanup 1.52 #21692 finally figure it out, comment 0.13 #21686 testing and comment 0.57 #16535 research and close 0.12 #16529 research and close
5.97
2023/12/07 Thursday 0.38 #17457 rebase, retest, push for CI 2.03 #17435 testing, work on a fix, more testing 0.35 #21679 apply to blead, perldelta 0.75 #13814 changes per comments
3.61
2023/12/08 Friday 0.35 #21696 apply to blead, update dist/IO/Changes
0.60
2023/12/11 Monday 0.20 #21684 follow-up 0.72 #21701 research and comment 0.63 #21705 research and comment 0.60 #21702 testing, research and approve 0.08 #21706 review and approve 0.13 #21703 review and approve 0.08 #21699 review and approve 0.08 #21698 review and approve 0.08 #21704 review and approve 0.17 #21700 review and approve 1.03 #21701 testing, research, comment 0.13 #21708 review and approve
4.08
2023/12/12 Tuesday 1.02 #21712 review the code, testing, comment (not a bug) 0.68 #21684 apply to blead, look at regenning the deps
1.93
2023/12/13 Wednesday 0.27 #21705 research and comment 0.22 #21710 review and approve 2.38 #21714 review and approve, comment 0.27 #21711 review and approve 0.18 #21713 review and approve 0.40 #21676 review and approve
6.14
2023/12/14 Thursday 0.12 #21714 follow-up 1.83 #21701 testing and research, comment
2.58
2023/12/18 Monday 0.42 #21725 debugging, comment 1.38 #21716 debugging. research, comment, work on a fix, push
1.80
2023/12/19 Tuesday 1.08 #21716 minor fixes, testing and comments 0.62 #21725 add comment 0.85 #21719 review, research and comments
2.87
2023/12/20 Wednesday 0.45 #21723 review, research and approve 0.18 #21726 review, research (alternate openbsd libc anywhere?, apparently not), approve 0.23 #21728 review and approve 0.58 #21720 review, comments and approve 0.25 #21731 follow-up comment 0.70 #21636 re-work 1.03 #21636 more re-work, testing and push 0.50 #21732 testing and comment, work on fixing the most
3.92
2023/12/21 Thursday 0.08 #21732 review discussion, check CI results and create PR 21737 0.20 #21716 review discussion and comment 0.15 #21719 review updates and approve
1.48
Which I calculate is 43.3 hours.
Approximately 44 tickets were reviewed or worked on, and 5 patches were applied. ```
Published by Gabor Szabo on Monday 11 March 2024 07:47
Originally published at Perl Weekly 659
My father was a chess player. In his best time he was sometimes called "the best non-Russian chess player". He survived WWII and the Holocaust in a Hungarian forced labor camp and in Russian POV camp. When he got back to Hungary all he wanted to do is get back to chess. He did not want to care about 'politics'.
In the 90s he often lamented that he did not pay enough attention to what went on in Hungary in the 50's. That he was not aware of the communist atrocities in Hungary and neighboring countries.
I have been publishing the Perl Weekly for more than 12 years. In the first 9-10 year I think I have never mentioned anything besides Perl or related technologies. I wish I could keep focusing on technology only. Unfortunately I don't have that luxury any more.
Frankly, if we paid more attention to what's going on outside of Perl and outside of technology in general, maybe we would not be in such a bad situation.
On a related subject, I hear Garry Kasparov was added to the list of 'terrorists and extremists' by Russia.
We can't change the past - well, some do it anyway by lying about history - but we also cannot claim we did not know. We want to bring them home!
Have a better week!
--
Your editor: Gabor Szabo.
I think only a very little subset of programmers have such side projects and an even smaller subset write articles about these projects. For most people programming is a 9-5 job. It is not that others aren't as good or don't enjoy programming. It is just that they might have different hobbies, or no time for hobbies at all. Comment on Reddit or on DEV.to.
A very non-descriptive title for some logging/debugging advice.
How to remove packages?
The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from among all of the contributors during the month.
Welcome to a new week with a couple of fun tasks "Unique Occurrences" and "Dictionary Rank". If you are new to the weekly challenge then why not join us and have fun every week. For more information, please read the FAQ.
Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Banking Day Offset" and "Line Parser" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Do you know yapp? Want to quick introduction? You have to checkout this post.
Raku making good use of built-in support for Date. Raku rocks !!!
You will fall in love with Perl again when you see it's regex power. Keep it up great work.
Don't you love CPAN? Well it is the USP of Perl. Checkout how CPAN helped solve the task.
Using regex type of Raku make code looks clean and elegant. Well done.
Do you want to learn regex grammar then checkout this post. Cool work.
Magical Perl regex in action. No one can beat Perl in regex. Cool work.
Date::Names of Raku is used to solve this week task. Thanks for sharing knowledge with us.
A thorough solution to the Date task is not to be missed. Highly recommended.
This week Raku is the lucky language to be discussed with the power Date object. You also get seamless discussion as well.
This is what I was missing for so long. What a quality post we have. Thanks for your contribution.
Great CPAN modules released last week;
You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.
Want to see more? See the archives of all the issues.
Not yet subscribed to the newsletter? Join us free of charge!
(C) Copyright Gabor Szabo
The articles are copyright the respective authors.
Published on Sunday 10 March 2024 23:41
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given a start date and offset counter. Optionally you also get bank holiday date list. Given a number (of days) and a start date, return the number (of days) adjusted to take into account non-banking days. In other words: convert a banking day offset to a calendar day offset.
Non-banking days are:
Using Time::Piece the work can be contained in a single function. Really the main piece of logic required of sub count_days() is for us to check if a day is a weekend or bank holiday.
sub count_days{
my($start, $offset, $holidays) =
@_;
$start = Time::Piece->strptime($start, q/%Y-%m-%d/);
my $t = $start;
my $end = $start;
{
$t += ONE_DAY;
unless(
⟨The day is a weekend. 2 ⟩ ||
⟨The day is a bank holiday. 3 ⟩){
$end = $t;
$offset--;
}
redo if $offset > 0;
}
return $end->strftime(q/%Y-%m-%d/);
}
◇
Fragment referenced in 4.
1 == grep {$t->strftime(q/%Y-%m-%d/) eq $_}
@{$holidays}
◇
Fragment referenced in 1.
The rest of the code just tests this function.
MAIN:{
say count_days q/2018-06-28/, 3, [q/2018-07-03/];
say count_days q/2018-06-28/, 3;
}
◇
Fragment referenced in 4.
$ perl perl/ch-1.pl 2018-07-04 2018-07-03
You are given a line like below:
{% id field1=“value1”field2=“value2”field3=42 %}
Where
The line parser should return a structure like:
{ name => id, fields => { field1 => value1, field2 => value2, field3 => value3, } }
It should be able to parse the following edge cases too:
{% youtube title="Title␣\"quoted\"␣done" %}
and
{% youtube title="Title␣with␣escaped␣backslash␣\\" %}
Most of the work is done in a parser constructed using Parse::Yapp.
First off, before we get into the parser, here is a small bit of code for driving the tests.
sub print_record{
my($record) =
@_;
say q/{/;
say qq/\tname => / . $record->{name};
say qq/\tfields => {/;
for my $field (sort {$a cmp $b} keys %{$record->{fields}}){
say qq/\t\t$field => / . q/ / . $record->{fields}->{$field};
}
say qq/\t}/;
say q/}/;
}
◇
Fragment referenced in 8.
The rest of the code drives some tests.
use v5.38;
use Ch2;
use constant TEST0 => q/{% id field1="value1" field2="value2" field3=42 %}/;
use constant TEST1 => q/{% youtube title="Title␣\"quoted\"␣done" %}/;
use constant TEST2 => q/{% youtube title="Title␣with␣escaped␣backslash␣\\\\" %}/;
◇
Fragment referenced in 8.
MAIN:{
my $parser = Ch2->new();
say TEST0;
print_record($parser->parse(TEST0));
say TEST1;
print_record($parser->parse(TEST1));
say TEST2;
print_record($parser->parse(TEST2));
}
◇
Fragment referenced in 8.
Here is where the work is really done. Parse::Yapp is given the following grammar. A parser is generated, contained in it’s own module.
First off is the grammar’s header. Here we define the symbols used in the rules which follow. We also add a small code block which contains a hash for holding the structure obtained from the parsed text.
%token NUMBER
%token START
%token END
%token WORD
%token QUOTE
%token ESCAPED_QUOTE
%{
my %record = (fields => {});
%}
◇
Fragment referenced in 17.
Here is the most important section, the rules for processing the input! For some rules we have also added action code blocks. We want to construct a data structure from the given input and in these action code blocks that final result is accumulated. Remember, the first rule is going to be called last, when the input is complete, so there we give a reference to a hash containing the result. This is the return value for the parse function found in the grammar’s footer.
file: START id fields END {$record{name} = $_[2]; \%record;}
;
id: WORD
;
words: WORD
| words WORD
| words ESCAPED_QUOTE WORD ESCAPED_QUOTE
;
field: WORD ’=’ NUMBER {$record{fields}->{$_[1]} = $_[3]}
| WORD ’=’ QUOTE words QUOTE {$record{fields}->{$_[1]} = $_[4]}
;
fields: field
| fields field
;
◇
Fragment referenced in 17.
The footer contains additional Perl code for the lexer, error handing, and a parse function which provides the main point of execution from code that wants to call the parser that has been generated from the grammar.
The lexer function is called repeatedly for the entire input. Regular expressions are used to identify symbols (the ones declared in the header) and pass them along for the rules processing.
sub lexer{
my($parser) =
@_;
$parser->YYData->{INPUT} or return(’’, undef);
$parser->YYData->{INPUT} =~ s/^[ \t]//g;
##
# send tokens to parser
##
for($parser->YYData->{INPUT}){
s/^([0-9]+)// and return ("NUMBER", $1);
s/^({%)// and return ("START", $1);
s/^(%})// and return ("END", $1);
s/^(\w+)// and return ("WORD", $1);
s/^(=)// and return ("=", $1);
s/^(")//␣and␣return␣("QUOTE",␣$1);
s/^(\\")//␣and␣return␣("ESCAPED_QUOTE",␣$1);
s/^(\\\\)// and return ("WORD", $1);
}
}
◇
Fragment referenced in 16.
The parse function is for the convenience of calling the generated parser from other code. yapp will generate a module and this will be the module’s method used by other code to execute the parser against a given input.
Notice here that we are squashing white space, both tabs and spaces, using tr. This reduces all repeated tabs and spaces to a single one. The eases further processing since extra whitespace is just ignored, according to the rules we’ve been given.
Also notice the return value from parsing. In the rules section we provide a return value, a hash reference, in the final action code block executed.
sub parse{
my($self, $input) =
@_;
$input =~ tr/\t/ /s;
$input =~ tr/ //s;
$self->YYData->{INPUT} = $input;
my $result = $self->YYParse(yylex => \\&lexer, yyerror => \\&error);
return $result;
}
◇
Fragment referenced in 16.
This is really just about the most minimal error handling function there can be! All this does is print “syntax error”when the parser encounters a problem.
sub error{
exists $_[0]->YYData->{ERRMSG}
and do{
print $_[0]->YYData->{ERRMSG};
return;
};
print "syntax␣error\n";
}
◇
Fragment referenced in 16.
$ yapp -m Ch2 perl/ch-2.yp; mv Ch2.pm perl; perl -I. ch-2.pl {% id field1="value1" field2="value2" field3=42 %} { name => id fields => { field1 => value1 field2 => value2 field3 => 42 } } {% youtube title="Title␣\"quoted\"␣done" %} { name => youtube fields => { field1 => value1 field2 => value2 field3 => 42 title => Title } } {% youtube title="Title␣with␣escaped␣backslash␣\\" %} { name => youtube fields => { field1 => value1 field2 => value2 field3 => 42 title => Title } }
Published by glycine on Saturday 09 March 2024 22:11
Show code for TL;DR:
use Bio::AlignIO;
my $in = Bio::AlignIO->new(
-file => $inputfilename ,
-format => 'fasta',
);
while ( my $aln = $in->next_aln() ) {
foreach my $seq ($aln->each_seq) {
...; # do some thing
}
}
Bio::Perl is a famous library for managing bioinformatics data, although all knowledge mentioned here can fetch from documents on cpan or Bio::Perl webpages, but I believe there can be numerous articles to explain the same thing. :)
The most difficult aspect for me is understanding which classes' documentation should I read, which object will be generated? and then, which method on which object do I need to invoke for the data I wanted?
so let me descript how a Bio::AlignIO object formed.
Bio::AlignIO
object can contain multiple alignments.
Bio::SimpleAlign
contains one alignment.
Bio::LocatableSeq
contains one aligned sequence.
For example, let's presume I have a file containing COI alignment for ten samples. If I use this file to call Bio::AlignIO->new()
, the new Bio::AlignIO
object will contain only one Bio::SimpleAlign
object which contains this COI alignment. Then, the Bio::SimpleAlign
object contains ten Bio::LocatableSeq
objects for aligned COI sequences of each sample.
one alignment is tranditional one gene or multiple genes alignment, e.g., a COI alignment in here. Usually this type of alignment data is stored one file like phylip, nexus or fasta. but Bio::AlignIO
can manage blast output, too. so Authors keep the ability of contain multiple alignments in one Bio::AlignIO
object. In my condition, I just directly get first Bio::SimpleAlign
from it.
Today I just wanted to retrieve the sequences of each sample in my alignment file (fasta) and import them into Perl. To achieve this, first, we need to call the new method to create a new Bio::AlignIO
object, using the alignment file as an argument:
my $in = Bio::AlignIO->new(
-file => $inputfilename,
-format => 'fasta',
);
Then, we want to extract Bio::SimpleAlign
objects from the Bio::AlignIO
object. For convenience, we use the same method as described in the Bio::AlignIO
documentation. We use a while loop to iterate through each Bio::SimpleAlign
object contained in the Bio::AlignIO
object (although we know there is only one):
while ( my $aln = $in->next_aln() ) { ... ;}
Now, we need to extract Bio::LocatableSeq
objects from Bio::SimpleAlign
. Calling the each_seq()
method of Bio::SimpleAlign
allows us to retrieve Bio::LocatableSeq
objects, each storing a sequence:
foreach my $seq ($aln->each_seq) { ...; }
At this point, we're nearly done. Simply by calling the seq()
and id()
methods of Bio::LocatableSeq
objects, we can obtain the sequence ID and the actual sequence data. For instance, to print out the base pairs of each sequence:
foreach my $seq ($aln->each_seq) {print $seq->seq(), "\n"}
References:
Published by Unknown on Saturday 09 March 2024 22:04
I can’t be the only programmer who does this. You’re looking for an online service to fill some need in your life. You look at three or four competing products and they all get close but none of them do everything you want. Or maybe they do tick all the boxes but they cost that little bit more than you’re comfortable paying. After spending a few hours on your search that little voice pops up in your head with that phrase that you really don’t want to hear:
Maybe you should just write your own version. How hard can it be?
A couple of hours later, you have something that vaguely works, you’ve learned more than you thought there was to learn about some obscure corner of life and you’re the proud owner of another new domain.
Please tell me it’s not just me.
So today I’ve been working on my Linktree clone.
Honestly, I can’t remember what it was about Linktree or its existing clones that I didn’t like. I suspect it’s that I just wanted more control over my links page than a hosted service would give me. All I can be sure of is that in September 2022 I made the first commit to a project that, eighteen months later, I’m still maintaining and improving.
To be fair to myself, I didn’t buy a new domain. That means I’m getting better, right? The output is hosted at links.davecross.co.uk. I’m not even paying for hosting as it’s all hosted on GitHub Pages – it’s a static site that has occasional changes, so it’s perfect for GitHub Pages.
But I have spent quite a lot of time working on the code. Probably more than is reasonable for a web site that gets a dozen visits in a good month. Work on it seems to come in waves. I’ll go for months without touching it, and then I’ll spend a week or so working on it pretty much every day. Over the last 24 hours or so, I’ve passed an important milestone. Like all of these little side projects, this one started out as a largely unstructured code dump – as I worked to get it doing something that approximated the original goal. Then I’ll spend some time (months, usually) where fixes and improvements are implemented by hacking on the original horrible code. At some point. I’ll realise that I’m making things too difficult for myself and I’ll rewrite it (largely from scratch) to be better structured and easier to maintain. That’s where I got to today. The original single-file code dump has been rewritten into something that’s far nicer to work on. And as a side benefit, I’ve rewritten it all using Perl’s new, built-in object orientation features – which I’m loving.
Oh, and I guess that’s the upside of having little side projects like this – I get to try out new features like the new OO stuff in a no-pressure environment. And just spending time doing more programming has to make you a better programmer, right? And surely it’s just a matter of time before one of these projects takes off and turns me into a millionaire! I’m not saying for a minute that having pointless side projects is a bad idea. I’m just wondering how many pointless side projects are too many
So, that’s my guilty secret – I’m a serial writer of code that doesn’t really need to be written. What about you? How many pointless side projects do you have? And how much of your spare time do they use up?
The post Pointless personal side projects appeared first on Perl Hacks.
Published by Perl Steering Council on Thursday 07 March 2024 22:28
Just Paul and Philippe this week:
In absence of many other pressing issues, we spent some time thinking ahead to large-scale development work that might take place in the 5.41 series. We talked about “hooks” as a potential long-term thought to making a more powerful Magic-like structure, for implementing new features, attributes, etc..
Published by alh on Tuesday 05 March 2024 12:33
Paul writes:
``` Hours:
1 = Allow space in -M
option
https://github.com/Perl/perl5/pull/21935
3 = Tidy up / remove builtin
unimport logic
https://github.com/Perl/perl5/pull/22002
https://github.com/Perl/perl5/pull/22009
5.5 = use VERSION
restrictions
https://github.com/Perl/perl5/pull/21980
https://github.com/Perl/perl5/pull/21997
https://github.com/Perl/perl5/pull/22057
1 = class.c bugfix https://github.com/Perl/perl5/pull/21957
2 = builtin::numify https://github.com/Perl/perl5/pull/21982
1 = Tests for class.c non-ASCII UTF-8 https://github.com/Perl/perl5/pull/21983
1.5 = Logical xor operator (^^) https://github.com/Perl/perl5/pull/21996
Total: 15 hours. ```
Published by alh on Tuesday 05 March 2024 07:44
Dave writes:
(this report covers two months)
This is my monthly report on work done during Jan,Feb 2024 covered by my TPF perl core maintenance grant.
I spent the last two months mainly on two goals.
1) Understanding XS better so that I can then decide how to update the XS ecosystem to better support a reference-counted stack; as an example, automatically removing the need to call XSUBs via a wrapper in some circumstances.
Doing this led me down a rabbit hole of realising how awful our current XS documentation is. Just about every section I read resulted in confusion, followed by time out to experiment and/or to look at the ParseXS src code to try to understand what the documentation was trying to tell me. It's also very out of date: telling us of exciting "new" features introduced 25 years ago.
The net result of this is that I now have about 1000 lines of notes on "things to fix in the XS docs". I intend sometime soon to completely revamp perlxs.pod and perlxstut.pod, based on these notes. Which is a bit of sidetrack from getting XS working better under PERL_RC_STACK builds. And doing PERL_RC_STACK was itself initially a sidetrack from doing more work on perl signatures. Such is often the way when working on perl.
2) General small tasks to help get blead into shape for the 5.40 release, such as analysing and reducing smoke failures, fixing bugs, and fixing any Deparse regressions that have crept in over the last year.
SUMMARY:
* 0:38 #21822: BBC: Blead Breaks Variable::Magic
* 1:20 #21876: BBC: 5.39.7 breaks GONZUS/Cache-utLRU-0.002000.tar.gz
* 3:21 #21969: clone-with-stack.t crash
* 2:17 fix Test -deparse failures
* 1:35 fix minitest failures
* 3:39 make __LINE__
etc Deparse batter
* 1:57 make stack reference counted
* 30:30 make stack reference counted - XS
* 19:46 process p5p mailbox
* 1:28 reduce build stderr noise
* 8:33 reduce smoke failures
TOTAL: * 75:04 (HH::MM)
Published on Sunday 03 March 2024 16:52
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given an array of positive integers, @ints. Write a script to find out how many integers have even number of digits.
The majory of the work can be done in a single line. Conveniently the tr function returns the number of characters effected by the command. For our purposes that means telling tr to delete all numerals. We then check if the number of numerals removed is even inside of a grep block. The number of matches is then returned. Note the one catch, in order to use tr we need to assign $_ to a temporary value, $x. Otherwise we would get an error Modification of a read-only value.
sub count_even_digits{
return 0 +
grep {
my $x = $_; $x =~ tr/[0-9]//d % 2 == 0
}
@_;
}
◇
Fragment referenced in 2.
The rest of the code just tests this function.
MAIN:{
say count_even_digits 10, 1, 111, 24, 1000;
say count_even_digits 111, 1, 11111;
say count_even_digits 2, 8, 1024, 256;
}
◇
Fragment referenced in 2.
$ perl perl/ch-1.pl 3 0 1
You are given an array of integers, @int and an integer $k. Write a script to find the sum of values whose index binary representation has exactly $k number of 1-bit set.
First, let’s concern ourselves with counting set bits. Here we can re-use some code that we’ve used before. This is a pretty standard way to count bits. This procedure is to do a bitwise AND operation for the least significant bit and check if it is set. We then right shift and repeat until no bits remain. This code is actually a modification of code used in TWC 079!
sub count_bits{
my($x) =
@_;
my $total_count_set_bit = 0;
while($x){
my $b = $x & 1;
$total_count_set_bit++ if $b;
$x = $x >> 1;
}
return $total_count_set_bit;
}
◇
Fragment referenced in 7.
With that necessary work taken care of we need to loop over the given array of integers and (1) check to see if the index contains the correct number of set bits and, if that is the case, add to the rolling sum. Finally, return the sum.
sub sum_of_values{
my $k = shift;
my(
@n) =
@_;
my $sum;
do{
$sum += $_[$_] if count_bits($_) == $k;
} for 0 ..
@n - 1;
return $sum;
}
◇
Fragment referenced in 7.
The rest of the code drives some tests.
MAIN:{
say sum_of_values 1, 2, 5, 9, 11, 3;
say sum_of_values 2, 2, 5, 9, 11, 3;
say sum_of_values 0, 2, 5, 9, 11, 3;
}
◇
Fragment referenced in 7.
$ perl perl/ch-2.pl 17 11 2
Published by Unknown on Sunday 03 March 2024 08:47
Published by laurent_r on Saturday 02 March 2024 16:07
These are some answers to the Week 258, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a couple of days from now (on March 3, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
You are given an array of integers, @int
and an integer $k
.
Write a script to find the sum of values whose index binary representation has exactly $k
number of 1-bit set.
Example 1
Input: @ints = (2, 5, 9, 11, 3), $k = 1
Output: 17
Binary representation of index 0 = 0
Binary representation of index 1 = 1
Binary representation of index 2 = 10
Binary representation of index 3 = 11
Binary representation of index 4 = 100
So the indices 1, 2 and 4 have total one 1-bit sets.
Therefore the sum, $ints[1] + $ints[2] + $ints[4] = 17
Example 2
Input: @ints = (2, 5, 9, 11, 3), $k = 2
Output: 11
Example 3
Input: @ints = (2, 5, 9, 11, 3), $k = 0
Output: 2
Although it could easily be done in a one-liner, I've decided to split the solution in two statements, for the sake of clarity. The first statement finds the indexes whose binary representation contains exactly $k
"1" (sum of digits equal to $k
) and populates the @eligibles
array with the corresponding input values in @in
. The second statement simply returns the sum oh those values.
sub sum-of-values ($k, @in) {
my @eligibles = map { @in[$_] },
grep {$_.base(2).comb.sum == $k}, 0..@in.end;
return @eligibles.sum;
}
my @tests = (1, <2 5 9 11 3>),
(2, <2 5 9 11 3>),
(0, <2 5 9 11 3>);
for @tests -> @test {
printf "%-15s => ", "@test[]";
say sum-of-values @test[0], @test[1];
}
This program displays the following output:
$ raku ./sum-of-values.raku
1 2 5 9 11 3 => 17
2 2 5 9 11 3 => 11
0 2 5 9 11 3 => 2
This is a port to Perl of the above Raku program. I counted the number of "1" using the tr///
operator because has no built-in sum
function, only to find moments later that I needed to implement a sum
subroutine anyway.
use strict;
use warnings;
use feature 'say';
sub sum {
my $sum = 0;
$sum += $_ for @_;
return $sum;
}
sub sum_of_values {
my ($k, @in) = @_;
my @eligibles = map { $in[$_] }
grep {sprintf ("%b", $_) =~ tr/1/1/ == $k} 0..$#in;
return sum @eligibles;
}
my @tests = ( [1, [<2 5 9 11 3>]],
[2, [<2 5 9 11 3>]],
[0, [<2 5 9 11 3>]] );
for my $test (@tests) {
printf "%-3s - %-15s => ", "$test->[0]", "@{$test->[1]}";
say sum_of_values $test->[0], @{$test->[1]};
}
This program displays the following output:
$ perl ./sum-of-values.pl
1 - 2 5 9 11 3 => 17
2 - 2 5 9 11 3 => 11
0 - 2 5 9 11 3 => 2
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on March 10, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Published by perlancar on Friday 01 March 2024 00:00
dist | author | abstract | date |
---|---|---|---|
Acme-CPANModules-ArrayData | PERLANCAR | List of modules related to ArrayData | 2024-02-05T00:05:46 |
Acme-CPANModules-FormattingDate | PERLANCAR | List of various methods to format dates | 2024-02-18T14:01:27 |
Acme-CPANModules-HashData | PERLANCAR | List of modules related to HashData | 2024-02-06T00:05:32 |
Acme-CPANModules-Import-CPANRatings-User-davidgaramond | PERLANCAR | List of modules mentioned by CPANRatings user davidgaramond | 2024-02-28T00:05:24 |
Acme-CPANModules-InfoFromCPANTesters | PERLANCAR | List of distributions that gather information from CPANTesters | 2024-02-18T14:03:11 |
Acme-CPANModules-InterestingTies | PERLANCAR | List of interesting uses of the tie() interface | 2024-02-29T00:05:11 |
Acrux-DBI | ABALAMA | Database independent interface for Acrux applications | 2024-02-05T18:44:46 |
Alien-Cowl | ZMUGHAL | Find or build Cowl | 2024-02-15T03:24:53 |
Alien-Qhull | DJERIUS | Build and Install the Qhull library | 2024-02-09T17:38:52 |
AnyEvent-Sway | JOHNMERTZ | communicate with the Sway window manager | 2024-02-09T00:42:07 |
App-GnuCash-MembershipUtils | PDURDEN | A group of perl modules and scripts to help in using GnuCash for membership. | 2024-02-27T02:41:31 |
App-ISBN-Check | SKIM | Tool for ISBN checking. | 2024-02-25T18:59:34 |
App-MARC-Record-Stats | SKIM | Tool to work with MARC::Record::Stats on MARC dataset. | 2024-02-21T11:20:06 |
App-MergeCal | DAVECROSS | 2024-02-02T17:37:26 | |
App-Prove-Plugin-TestArgs | SVW | A prove plugin to configure test aliases and arguments | 2024-02-07T12:49:02 |
App-cdbookmark | PERLANCAR | Change directory to one from the list | 2024-02-03T00:05:45 |
App-grep-similar-text | PERLANCAR | Print lines similar to the specified text | 2024-02-01T00:06:12 |
App-zen | LITCHIE | Zen is a markdown based literate programming tool | 2024-02-05T05:48:06 |
Bencher-Scenarios-Log-Dispatch | PERLANCAR | Bencher scenarios related to Log::Dispatch modules | 2024-02-04T00:05:28 |
Bencher-Scenarios-Log-Dispatch-FileRotate | PERLANCAR | Scenarios to benchmark Log::Dispatch::FileRotate | 2024-02-11T00:05:41 |
Bundle-WATERKIP | WATERKIP | A mono repo for perl scripts and modules which WATERKIP likes | 2024-02-27T23:00:33 |
Chess-ELO-FIDE | NICEPERL | Download and store FIDE ratings | 2024-02-24T19:06:41 |
Common-Log-Parser | RRWO | Parse the common log format lines used by Apache | 2024-02-09T15:12:27 |
Comparer | PERLANCAR | Reusable comparer subroutines | 2024-02-08T00:11:13 |
Comparer-by_similarity | PERLANCAR | Compare similarity to a reference string | 2024-02-23T02:06:32 |
Comparer-similarity | PERLANCAR | Compare similarity to a reference string | 2024-02-24T00:06:09 |
DBIx-Class-FilterColumn-Encrypt | LEONT | Transparently encrypt columns in DBIx::Class | 2024-02-03T15:22:04 |
Dancer2-Controllers | RAWLEYFOW | A tool to allow OO style route declaration in Dancer2 | 2024-02-14T22:00:57 |
Data-Login | SKIM | Data objects for login. | 2024-02-05T22:13:16 |
Data-Sah-FilterBundle-Filename-Safe | PERLANCAR | Sah filters related to removing problematic characters from filename | 2024-02-10T00:06:19 |
Data-Structure-Deserialize-Auto | TYRRMINAL | Deserializes data structures from perl, JSON, YAML, or TOML data, from strings or files | 2024-02-22T18:13:45 |
Data-Text-Simple | SKIM | Data objects for text in language. | 2024-02-29T17:29:50 |
Data-Transfigure | TYRRMINAL | performs rule-based data transfigurations of arbitrary structures | 2024-02-19T20:39:03 |
Date-Holidays-CW | WATERKIP | Curacoa's official holidays | 2024-02-08T07:49:12 |
Devel-Confess-Source-Patch-ExcludePackage | PERLANCAR | Exclude some packages from source trace | 2024-02-25T00:05:42 |
Dist-Zilla-Plugin-GitHub-Offline | LEONT | Add a GitHub repo's info to META.{yml,json} | 2024-02-06T19:19:02 |
File-Util-Rename | PERLANCAR | Utilities related to renaming files | 2024-02-12T00:06:03 |
Games-Sudoku-Html | SHE | Visualize and play collections of standard 9×9 Sudoku in your browser. | 2024-02-24T20:23:44 |
Games-Sudoku-Pdf | SHE | Produce pdf files from your digital Sudoku sources or collections. | 2024-02-24T19:57:08 |
Locale-CLDR-Locales-Aa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Afar ) | 2024-02-25T13:32:59 |
Locale-CLDR-Locales-Ab | JGNI | Locale::CLDR – Data Package ( Perl localization data for Abkhazian ) | 2024-02-25T13:34:25 |
Locale-CLDR-Locales-An | JGNI | Locale::CLDR – Data Package ( Perl localization data for Aragonese ) | 2024-02-25T13:39:26 |
Locale-CLDR-Locales-Ann | JGNI | Locale::CLDR – Data Package ( Perl localization data for Obolo ) | 2024-02-25T13:40:49 |
Locale-CLDR-Locales-Apc | JGNI | Locale::CLDR – Data Package ( ) | 2024-02-25T13:42:12 |
Locale-CLDR-Locales-Arn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Mapuche ) | 2024-02-25T13:43:47 |
Locale-CLDR-Locales-Ba | JGNI | Locale::CLDR – Data Package ( Perl localization data for Bashkir ) | 2024-02-25T13:49:23 |
Locale-CLDR-Locales-Bal | JGNI | Locale::CLDR – Data Package ( Perl localization data for Baluchi ) | 2024-02-25T13:49:34 |
Locale-CLDR-Locales-Bew | JGNI | Locale::CLDR – Data Package ( Perl localization data for Betawi ) | 2024-02-25T13:54:02 |
Locale-CLDR-Locales-Bgc | JGNI | Locale::CLDR – Data Package ( Perl localization data for Haryanvi ) | 2024-02-25T13:56:59 |
Locale-CLDR-Locales-Bgn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Western Balochi ) | 2024-02-25T13:57:19 |
Locale-CLDR-Locales-Bho | JGNI | Locale::CLDR – Data Package ( Perl localization data for Bhojpuri ) | 2024-02-25T13:58:45 |
Locale-CLDR-Locales-Blo | JGNI | Locale::CLDR – Data Package ( Perl localization data for Anii ) | 2024-02-25T14:00:25 |
Locale-CLDR-Locales-Blt | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tai Dam ) | 2024-02-25T14:00:36 |
Locale-CLDR-Locales-Bss | JGNI | Locale::CLDR – Data Package ( Perl localization data for Akoose ) | 2024-02-25T14:08:19 |
Locale-CLDR-Locales-Byn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Blin ) | 2024-02-25T14:08:31 |
Locale-CLDR-Locales-Cad | JGNI | Locale::CLDR – Data Package ( Perl localization data for Caddo ) | 2024-02-25T14:11:41 |
Locale-CLDR-Locales-Cch | JGNI | Locale::CLDR – Data Package ( Perl localization data for Atsam ) | 2024-02-25T14:11:52 |
Locale-CLDR-Locales-Cho | JGNI | Locale::CLDR – Data Package ( Perl localization data for Choctaw ) | 2024-02-25T14:16:44 |
Locale-CLDR-Locales-Cic | JGNI | Locale::CLDR – Data Package ( Perl localization data for Chickasaw ) | 2024-02-25T14:19:31 |
Locale-CLDR-Locales-Co | JGNI | Locale::CLDR – Data Package ( Perl localization data for Corsican ) | 2024-02-25T14:21:02 |
Locale-CLDR-Locales-Csw | JGNI | Locale::CLDR – Data Package ( Perl localization data for Swampy Cree ) | 2024-02-25T14:22:49 |
Locale-CLDR-Locales-Cv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Chuvash ) | 2024-02-25T14:25:39 |
Locale-CLDR-Locales-Dv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Divehi ) | 2024-02-25T14:35:09 |
Locale-CLDR-Locales-Frr | JGNI | Locale::CLDR – Data Package ( Perl localization data for Northern Frisian ) | 2024-02-25T14:51:31 |
Locale-CLDR-Locales-Gaa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Ga ) | 2024-02-25T14:54:34 |
Locale-CLDR-Locales-Gez | JGNI | Locale::CLDR – Data Package ( Perl localization data for Geez ) | 2024-02-25T14:57:36 |
Locale-CLDR-Locales-Gn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Guarani ) | 2024-02-25T14:59:14 |
Locale-CLDR-Locales-Hnj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Hmong Njua ) | 2024-02-25T15:09:00 |
Locale-CLDR-Locales-Ie | JGNI | Locale::CLDR – Data Package ( Perl localization data for Interlingue ) | 2024-02-25T15:20:31 |
Locale-CLDR-Locales-Io | JGNI | Locale::CLDR – Data Package ( Perl localization data for Ido ) | 2024-02-25T15:23:42 |
Locale-CLDR-Locales-Iu | JGNI | Locale::CLDR – Data Package ( Perl localization data for Inuktitut ) | 2024-02-25T15:26:52 |
Locale-CLDR-Locales-Jbo | JGNI | Locale::CLDR – Data Package ( Perl localization data for Lojban ) | 2024-02-25T15:28:43 |
Locale-CLDR-Locales-Kaj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Jju ) | 2024-02-25T15:34:54 |
Locale-CLDR-Locales-Kcg | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tyap ) | 2024-02-25T15:36:25 |
Locale-CLDR-Locales-Ken | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kenyang ) | 2024-02-25T15:39:38 |
Locale-CLDR-Locales-Kpe | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kpelle ) | 2024-02-25T15:51:57 |
Locale-CLDR-Locales-Kxv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kuvi ) | 2024-02-25T15:59:25 |
Locale-CLDR-Locales-La | JGNI | Locale::CLDR – Data Package ( Perl localization data for Latin ) | 2024-02-25T16:01:00 |
Locale-CLDR-Locales-Lij | JGNI | Locale::CLDR – Data Package ( Perl localization data for Ligurian ) | 2024-02-25T16:05:34 |
Locale-CLDR-Locales-Lmo | JGNI | Locale::CLDR – Data Package ( Perl localization data for Lombard ) | 2024-02-25T16:07:06 |
Locale-CLDR-Locales-Mdf | JGNI | Locale::CLDR – Data Package ( Perl localization data for Moksha ) | 2024-02-25T16:18:24 |
Locale-CLDR-Locales-Mic | JGNI | Locale::CLDR – Data Package ( Perl localization data for Mi'kmaw ) | 2024-02-25T16:25:46 |
Locale-CLDR-Locales-Moh | JGNI | Locale::CLDR – Data Package ( Perl localization data for Mohawk ) | 2024-02-25T16:30:37 |
Locale-CLDR-Locales-Mus | JGNI | Locale::CLDR – Data Package ( Perl localization data for Muscogee ) | 2024-02-25T16:35:33 |
Locale-CLDR-Locales-Myv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Erzya ) | 2024-02-25T16:38:20 |
Locale-CLDR-Locales-Nqo | JGNI | Locale::CLDR – Data Package ( Perl localization data for N’Ko ) | 2024-02-25T16:49:31 |
Locale-CLDR-Locales-Nr | JGNI | Locale::CLDR – Data Package ( Perl localization data for South Ndebele ) | 2024-02-25T16:49:40 |
Locale-CLDR-Locales-Nso | JGNI | Locale::CLDR – Data Package ( Perl localization data for Northern Sotho ) | 2024-02-25T16:51:06 |
Locale-CLDR-Locales-Nv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Navajo ) | 2024-02-25T16:52:52 |
Locale-CLDR-Locales-Ny | JGNI | Locale::CLDR – Data Package ( Perl localization data for Nyanja ) | 2024-02-25T16:54:29 |
Locale-CLDR-Locales-Oc | JGNI | Locale::CLDR – Data Package ( Perl localization data for Occitan ) | 2024-02-25T16:56:13 |
Locale-CLDR-Locales-Osa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Osage ) | 2024-02-25T16:59:38 |
Locale-CLDR-Locales-Pap | JGNI | Locale::CLDR – Data Package ( Perl localization data for Papiamento ) | 2024-02-25T17:02:20 |
Locale-CLDR-Locales-Pis | JGNI | Locale::CLDR – Data Package ( Perl localization data for Pijin ) | 2024-02-25T17:04:08 |
Locale-CLDR-Locales-Quc | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kʼicheʼ ) | 2024-02-25T17:10:41 |
Locale-CLDR-Locales-Raj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Rajasthani ) | 2024-02-25T17:10:54 |
Locale-CLDR-Locales-Rhg | JGNI | Locale::CLDR – Data Package ( Perl localization data for Rohingya ) | 2024-02-25T17:12:17 |
Locale-CLDR-Locales-Rif | JGNI | Locale::CLDR – Data Package ( Perl localization data for Riffian ) | 2024-02-25T17:13:41 |
Locale-CLDR-Locales-Scn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Sicilian ) | 2024-02-25T17:27:35 |
Locale-CLDR-Locales-Sdh | JGNI | Locale::CLDR – Data Package ( Perl localization data for Southern Kurdish ) | 2024-02-25T17:29:16 |
Locale-CLDR-Locales-Shn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Shan ) | 2024-02-25T17:36:55 |
Locale-CLDR-Locales-Sid | JGNI | Locale::CLDR – Data Package ( Perl localization data for Sidamo ) | 2024-02-25T17:37:33 |
Locale-CLDR-Locales-Skr | JGNI | Locale::CLDR – Data Package ( ) | 2024-02-25T17:40:13 |
Locale-CLDR-Locales-Sma | JGNI | Locale::CLDR – Data Package ( Perl localization data for Southern Sami ) | 2024-02-25T17:41:45 |
Locale-CLDR-Locales-Smj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Lule Sami ) | 2024-02-25T17:43:11 |
Locale-CLDR-Locales-Sms | JGNI | Locale::CLDR – Data Package ( Perl localization data for Skolt Sami ) | 2024-02-25T17:45:00 |
Locale-CLDR-Locales-Ss | JGNI | Locale::CLDR – Data Package ( Perl localization data for Swati ) | 2024-02-25T17:49:56 |
Locale-CLDR-Locales-Ssy | JGNI | Locale::CLDR – Data Package ( Perl localization data for Saho ) | 2024-02-25T17:51:22 |
Locale-CLDR-Locales-St | JGNI | Locale::CLDR – Data Package ( Perl localization data for Southern Sotho ) | 2024-02-25T17:51:52 |
Locale-CLDR-Locales-Syr | JGNI | Locale::CLDR – Data Package ( Perl localization data for Syriac ) | 2024-02-25T17:56:10 |
Locale-CLDR-Locales-Szl | JGNI | Locale::CLDR – Data Package ( Perl localization data for Silesian ) | 2024-02-25T17:57:55 |
Locale-CLDR-Locales-Tig | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tigre ) | 2024-02-25T18:04:08 |
Locale-CLDR-Locales-Tn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tswana ) | 2024-02-25T18:07:12 |
Locale-CLDR-Locales-Tok | JGNI | Locale::CLDR – Data Package ( Perl localization data for Toki Pona ) | 2024-02-25T18:08:49 |
Locale-CLDR-Locales-Tpi | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tok Pisin ) | 2024-02-25T18:09:03 |
Locale-CLDR-Locales-Trv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Taroko ) | 2024-02-25T18:13:13 |
Locale-CLDR-Locales-Trw | JGNI | Locale::CLDR – Data Package ( Perl localization data for Torwali ) | 2024-02-25T18:13:24 |
Locale-CLDR-Locales-Ts | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tsonga ) | 2024-02-25T18:15:02 |
Locale-CLDR-Locales-Tyv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tuvinian ) | 2024-02-25T18:18:06 |
Locale-CLDR-Locales-Ve | JGNI | Locale::CLDR – Data Package ( Perl localization data for Venda ) | 2024-02-25T18:24:31 |
Locale-CLDR-Locales-Vec | JGNI | Locale::CLDR – Data Package ( Perl localization data for Venetian ) | 2024-02-25T18:25:52 |
Locale-CLDR-Locales-Vmw | JGNI | Locale::CLDR – Data Package ( Perl localization data for Makhuwa ) | 2024-02-25T18:28:42 |
Locale-CLDR-Locales-Wa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Walloon ) | 2024-02-25T18:30:55 |
Locale-CLDR-Locales-Wal | JGNI | Locale::CLDR – Data Package ( Perl localization data for Wolaytta ) | 2024-02-25T18:33:42 |
Locale-CLDR-Locales-Wbp | JGNI | Locale::CLDR – Data Package ( Perl localization data for Warlpiri ) | 2024-02-25T18:33:50 |
Locale-CLDR-Locales-Xnr | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kangri ) | 2024-02-25T18:37:03 |
Locale-CLDR-Locales-Za | JGNI | Locale::CLDR – Data Package ( Perl localization data for Zhuang ) | 2024-02-25T18:44:50 |
Microsoft-Teams-WebHook | TYRRMINAL | Microsoft Teams WebHook with AdaptiveCards for formatting notifications | 2024-02-20T19:13:14 |
Mo-utils-IRI | SKIM | Mo utilities for IRI. | 2024-02-29T21:11:02 |
Mo-utils-URI | SKIM | Mo utilities for URI. | 2024-02-11T16:17:45 |
Mojolicious-Plugin-INIConfig-Extended | HESCO | Mojolicious Plugin to overload a Configuration | 2024-02-13T02:33:46 |
Mojolicious-Plugin-WebComponent | RES | An effort to make creating and using custom web components easier | 2024-02-29T16:06:39 |
Net-EANSearch | JANW | Perl module for EAN and ISBN lookup and validation using the API on https://www.ean-search.org | 2024-02-13T15:30:27 |
PDL-Opt-GLPK | SOMMREY | PDL interface to the GNU Linear Programming Kit | 2024-02-21T20:32:39 |
Perlgram-Bot | AMIRCANDY | 2024-02-26T10:23:19 | |
Plack-App-ChangePassword | SKIM | Plack change password application. | 2024-02-08T21:15:14 |
Pod-Weaver-Plugin-Sah-SchemaBundle | PERLANCAR | Plugin to use when building Sah::SchemaBundle::* distribution | 2024-02-26T00:06:02 |
RDF-Cowl | ZMUGHAL | A lightweight API for working with OWL 2 ontologies | 2024-02-15T03:37:41 |
SPVM-HTTP-Tiny | KIMOTO | HTTP Client | 2024-02-23T08:53:30 |
Sah-Schemas-Comparer | PERLANCAR | Sah schemas related to Comparer | 2024-02-16T00:06:37 |
Sah-Schemas-SortKey | PERLANCAR | Sah schemas related to SortKey | 2024-02-18T14:01:38 |
Sort-BySimilarity | PERLANCAR | Sort by most similar to a reference string | 2024-02-02T00:05:29 |
SortExample | PERLANCAR | Sort examples | 2024-02-27T00:05:08 |
SortKey | PERLANCAR | Reusable sort key generators | 2024-02-14T00:05:41 |
SortKey-Num-by_length | PERLANCAR | String length as sort key | 2024-02-15T00:05:40 |
SortKey-Num-length | PERLANCAR | String length as sort key | 2024-02-15T00:05:51 |
Sorter | PERLANCAR | Sorter | 2024-02-07T00:11:23 |
Sorter-by_similarity | PERLANCAR | Sort by most similar to a reference string | 2024-02-13T00:06:16 |
Tags-HTML-ChangePassword | SKIM | Tags helper for change password. | 2024-02-07T20:04:02 |
Tie-Hash-HashData | PERLANCAR | Access HashData object as a tied hash | 2024-02-09T00:05:25 |
Tk-AppWindow | HANJE | an application framework based on Tk | 2024-02-28T15:29:57 |
WWW-Suffit-Plugin-ConfigAuth | ABALAMA | The Suffit plugin for authentication and authorization providing via configuration | 2024-02-22T08:17:35 |
WWW-Suffit-Plugin-FileAuth | ABALAMA | The Suffit plugin for authentication and authorization by password file | 2024-02-22T11:39:04 |
WWW-Suffit-Plugin-SuffitAuth | ABALAMA | The Suffit plugin for Suffit API authentication and authorization providing | 2024-02-22T08:16:09 |
mojo-util-benchmark | CRLCU | A set of utilities for working with collections of data. | 2024-02-07T13:49:03 |
Number of new CPAN distributions this period: 155
Number of authors releasing new CPAN distributions this period: 26
Authors by number of new CPAN distributions this period:
No | Author | Distributions |
---|---|---|
1 | JGNI | 88 |
2 | PERLANCAR | 27 |
3 | SKIM | 8 |
4 | ABALAMA | 4 |
5 | TYRRMINAL | 3 |
6 | SHE | 2 |
7 | LEONT | 2 |
8 | ZMUGHAL | 2 |
9 | WATERKIP | 2 |
10 | LITCHIE | 1 |
11 | AMIRCANDY | 1 |
12 | HANJE | 1 |
13 | RAWLEYFOW | 1 |
14 | JOHNMERTZ | 1 |
15 | CRLCU | 1 |
16 | DJERIUS | 1 |
17 | JANW | 1 |
18 | SVW | 1 |
19 | PDURDEN | 1 |
20 | RES | 1 |
21 | HESCO | 1 |
22 | NICEPERL | 1 |
23 | SOMMREY | 1 |
24 | KIMOTO | 1 |
25 | RRWO | 1 |
26 | DAVECROSS | 1 |
Published by Dave Cross on Saturday 24 February 2024 15:22
The future is already here – it’s just not very evenly distributed
– William Gibson
The quotation above was used by Tim O’Reilly a lot around the time that Web 2.0 got going. Over recent months, I’ve had a few experiences that have made it clear to me that even the present isn’t particularly evenly distributed either. It’s always easy to find people still using technologies that we would consider archaic (and not in a rustic or hipster way).
We’ve known for twenty years that CGI is a bad idea. It’s almost ten years since CGI.pm was removed from Perl core. Surely, all of us are using something modern for web development these days.
Well, apparently not. CGI is alive and well and living on the fringes of the Perl community. I’ve come across it being used in some quite surprising places over the last year or so. I’m going to obfuscate some details in the following descriptions to, hopefully, prevent you (or, worse, the people involved) from recognising the companies involved.
None of this should be taken as an argument that the nms project was wrong to use CGI.pm or that the Perl 5 Porters were wrong to remove it from the Perl standard library. I still support both decisions. I just found it a bit jarring to be reminded that while we’re all using PSGI or Mojolicious to write microservices in Perl that serve REST APIs that are developed and deployed in Docker containers, there are still people out there who are struggling to FTP code that was written in 1997 onto low-end shared hosting.
I think this state of affairs has two causes. Firstly (like the first client I mentioned above) some systems were set up when CGI was still in common use – and things haven’t changed since. These people get a sudden shock when they are forced to move to a more modern server for some reason. And then there are people like my Fiverr clients who install Perl CGI programs because that’s what they have always done and they don’t know that there is an alternative approach. Part of the problem there is, presumably, that Perl has meant badly-written CGI programs for a large proportion of the web’s existence and means anyone searching for information on this subject is likely to find pages and pages of advice telling them how to install CGI programs before they discover anything about PSGI or Docker. And I think there might be a solution to that problem (or, at least, a way to nudge the web in the right direction).
Over last weekend I was cataloguing subdomains (I know how to have fun!) and I found a web site that I had forgotten about. I had obviously been contemplating a very similar situation back in 2016.
The site is called Perl Web Advice. The intention was (is?) that it would be a definitive source of good advice about how to develop and deploy web applications written in Perl. I had only made tiny inroads into the task before something else apparently seemed more fun and the project was abandoned.
But there’s the start of a framework for the site. And, this week, I’ve given it a GitHub Actions workflow so it gets republished automatically whenever changes are pushed to the repo. I’ve even set up a Dockerfile to make it easy to use the static site generator that I’ve used for it. So perhaps the idea has merit. Once there’s a bit more useful content there I could see if I can remember any of my SEO knowledge and get it appearing in results where people are looking for advice on this topic.
I would, of course, be happy to consider contributions from other people. What do you think? Would you like to help me save people from the hell of CGI deployments?
The post The present isn’t evenly distributed either appeared first on Perl Hacks.
I have lots of documents written in Markdown format and I was looking for a way to convert them to HTML.
Published by Makoto Nozaki on Wednesday 21 February 2024 17:20
We are seeking nominations for the 2024 White Camel Awards, which honor remarkable non-technical contributions in the Perl community. The Board will consider all nominations and will seek input both from the Advisory Board and the Perl Steering Council.
To nominate an individual, kindly complete the form at https://forms.gle/xQczcsRkguvaBDBn8.
In light of our community’s growing diversity, we kindly ask that the rationale for each nomination be articulated in a manner accessible to those who may not be familiar with the nominee.
For reference, previous recipients of this award can be found at https://whitecamel.org/.