#583 - Sponsoring Perl and other Open Source work

Perl Weekly

Published on Monday 26 September 2022 10:00

Hi there!

Happy New Year - Shana Tova - to all the Jews around the world!

A couple of days ago Ed Freyfogle wrote us pointig to their post on sponsoring MetaCPAN. I love this on so many levels. First of all, of course the fact that they sponsor some Perl-related activity. They also blog about it. They also send us a heads up to be included here in the Perl Weekly. I hope many more small and large companies, and also individuals will follow them.

Dean Hamstead also sent us an email linking to the new Perl Store, that was also announced on The Perl Foundation blog. Buying a T-shirt or some other swag will both help you with clothing and help TPF financially. Nice initiative!

Finally, I managed to set up my GitHub sponsors profile. So now, if you'd like to support my Perl and in more general Open Source work (articles, code, and videos) you can do so via GitHub as well. It would be awesome to get a few of you start supporting me via GitHub in the next couple of days. That will help things get rolling there and I would be able to see how the system really works.

Enjoy your week!

Support perl during October's Hacktoberfest. Running for the last nine years, this annual event is contributed to by thousands of coders and non coders world wide. However small or large, your input will make a difference.

Take a look at the Hacktoberfest website and get involved. You can also read about it on the Perl Blogs site.

Colin Crain › Perl Weekly Review #177

The Weekly Challenge

Published on Monday 26 September 2022 00:00

( …continues from previous week. ) Welcome to the Perl review pages for Week 177 of The Weekly Challenge! Here we will take the time to discuss the submissions offered up by the team, factor out some common methodologies that came up in those solutions, and highlight some of the unique approaches and unusual code created. ●︎ Why do we do these challenges? I suppose any reasonable answer to that question would come from a field as wide ranging and varied as the people who choose to join the team.

RECAP - The Weekly Challenge - 183

The Weekly Challenge

Published on Monday 26 September 2022 00:00

TABLE OF CONTENTS 01. HEADLINES 02. STAR CONTRIBUTORS 03. CONTRIBUTION STATS 04. GUESTS 05. LANGUAGES 06. CENTURION CLUB 07. DAMIAN CONWAY’s CORNER 08. ANDREW SHITOV’s CORNER 09. PERL SOLUTIONS 10. RAKU SOLUTIONS 11. PERL & RAKU SOLUTIONS HEADLINES Thank you Team PWC for your continuous support and encouragement. STAR CONTRIBUTORS Following members shared solutions to both tasks in Perl and Raku as well as blogged about it.

The Weekly Challenge - 184

The Weekly Challenge

Published on Monday 26 September 2022 00:00

TABLE OF CONTENTS 01. HEADLINES 02. SPONSOR 03. RECAP 04. PERL REVIEW 05. RAKU REVIEW 06. CHART 07. NEW MEMBERS 08. GUESTS 09. TASK #1: Sequence Number 10. TASK #2: Split Array HEADLINES Welcome to the Week #184 of The Weekly Challenge. Today, we are giving away Token #7 to Peter Campbell Smith for the book, Learning Perl Exercises by brian d foy. I will share the details with you in a separate email.

The Weekly Challenge - Guest Contributions

The Weekly Challenge

Published on Monday 26 September 2022 00:00

As you know, The Weekly Challenge, primarily focus on Perl and Raku. During the Week #018, we received solutions to The Weekly Challenge - 018 by Orestis Zekai in Python. It was pleasant surprise to receive solutions in something other than Perl and Raku. Ever since regular team members also started contributing in other languages like Ada, APL, Awk, BASIC, Bash, Bc, Befunge-93, Bourne Shell, BQN, Brainfuck, C3, C, CESIL, Chef, COBOL, Coconut, C Shell, C++, Clojure, Crystal, D, Dart, Dc, Elixir, Elm, Emacs Lisp, Erlang, Excel VBA, Fennel, Fish, Forth, Fortran, Gembase, GNAT, Go, Haskell, Haxe, HTML, Idris, IO, J, Janet, Java, JavaScript, Julia, Kotlin, Lisp, Logo, Lua, M4, Miranda, Modula 3, MMIX, Mumps, Myrddin, Nim, Nix, Node.

Perl Weekly Challenge 182: Unique Array and Date Difference

blogs.perl.org

Published by laurent_r on Sunday 25 September 2022 22:54

These are some answers to the Week 183 of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Task 1: Unique Array

You are given list of arrayrefs.

Write a script to remove the duplicate arrayrefs from the given list.

Example 1

Input: @list = ([1,2], [3,4], [5,6], [1,2])
Output: ([1,2], [3,4], [5,6])

Example 2

Input: @list = ([9,1], [3,7], [2,5], [2,5])
Output: ([9, 1], [3,7], [2,5])

Unique Array in Raku

The Raku solution is essentially a one-liner (more than one line because of the tests). We convert the sub-arrays into strings and use the unique built-in routine to remove duplicates.

for ([1,2], [3,4], [5,6], [1,2]), 
    ([9,1], [3,7], [2,5], [2,5]) -> @test {
    @test>>.map({"[$^a, $^b]"}).flat.unique.say;
}

This program displays the following output:

$ raku ./unique-arrays.raku
([1, 2] [3, 4] [5, 6])
([9, 1] [3, 7] [2, 5])

Unique Array in Perl

In Perl, we use the %unique hash to remove duplicates.

use strict;
use warnings;
use feature qw/say/;

for my $test ( [[1,2], [3,4], [5,6], [1,2]], 
               [[9,1], [3,7], [2,5], [2,5]] ) {
    my %unique = map { $_ => 1 } map { "[@$_]"} @$test;
    say join ", ",  keys %unique;
}

Note that, since this is not requested in the task specification, we’re not trying to keep the order of the input. It would be easy to keep the input order with an additional array.

This program displays the following output:

$ perl ./unique-arrays.pl
[3 4], [5 6], [1 2]
[3 7], [2 5], [9 1]

Task 2: Date Difference

You are given two dates, $date1 and $date2 in the format YYYY-MM-DD.

Write a script to find the difference between the given dates in terms on years and days only.

Example 1

    Input: $date1 = '2019-02-10'
           $date2 = '2022-11-01'
    Output: 3 years 264 days

Example 2

    Input: $date1 = '2020-09-15'
           $date2 = '2022-03-29'
    Output: 1 year 195 days

Example 3

    Input: $date1 = '2019-12-31'
           $date2 = '2020-01-01'
    Output: 1 day

Example 4

    Input: $date1 = '2019-12-01'
           $date2 = '2019-12-31'
    Output: 30 days

Example 5

    Input: $date1 = '2019-12-31'
           $date2 = '2020-12-31'
    Output: 1 year

Example 6

    Input: $date1 = '2019-12-31'
           $date2 = '2021-12-31'
    Output: 2 years

Example 7

    Input: $date1 = '2020-09-15'
           $date2 = '2021-09-16'
    Output: 1 year 1 day

Example 8

    Input: $date1 = '2019-09-15'
           $date2 = '2021-09-16'
    Output: 2 years 1 day

Date Difference in Raku

for ('2019-02-10', '2022-11-01'), 
    ('2020-09-15', '2022-03-29'),
    ('2019-12-31', '2020-01-01'),
    ('2019-12-01', '2019-12-31'),
    ('2019-12-31', '2020-12-31'),
    ('2019-12-31', '2021-12-31'),
    ('2020-09-15', '2020-09-16'),
    ('2019-09-15', '2021-09-16') -> @test {
    my @dates = map {Date.new($_) }, sort @test;
    my $delta-y = @dates[1].year - @dates[0].year;
    my ($y, $m, $d) = @dates[0].year, @dates[0].month.fmt("%02d"), 
        @dates[0].day.fmt("%02d");
    $delta-y -= 1 if "$m$d" > join "", @dates[1].month.fmt("%02d"), 
        @dates[1].day.fmt("%02d");
    $y += $delta-y;
    my $new-date = Date.new("$y-$m-$d");
    my $delta-d = @dates[1] - $new-date;
    say "@dates[]: $delta-y year(s) {$delta-d.fmt("%3d")} day(s)";
}

This script displays the following output:

$ raku ./date-diff.raku
2019-02-10 2022-11-01: 3 year(s) 264 day(s)
2020-09-15 2022-03-29: 1 year(s) 195 day(s)
2019-12-31 2020-01-01: 0 year(s)   1 day(s)
2019-12-01 2019-12-31: 0 year(s)  30 day(s)
2019-12-31 2020-12-31: 1 year(s)   0 day(s)
2019-12-31 2021-12-31: 2 year(s)   0 day(s)
2020-09-15 2020-09-16: 0 year(s)   1 day(s)
2019-09-15 2021-09-16: 2 year(s)   1 day(s)

Wrapping up

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

Unique Differences

dev.to #perl

Published by Simon Green on Sunday 25 September 2022 12:27

Weekly Challenge 183

Challenge, My solutions

Back after a short break :)

Task 1: Unique Array

Task

You are given list of arrayrefs.

Write a script to remove the duplicate arrayrefs from the given list.

My solutions

The logic in the Python and Perl solutions is basically the same. For each item in the outer list, see if it has appeared earlier in the list. In Python comparing two lists works as expected. I don't believe there is a way to do this in Perl, so I wrote an function called same_array to see if two arrays are the same.

Examples

$ ./ch-1.py "[[1,2], [3,4], [5,6], [1,2]]"
[1, 2], [3, 4], [5, 6]

$ ./ch-1.py "[[9,1], [3,7], [2,5], [2,5]]"
[9, 1], [3, 7], [2, 5]

Task 2: Date Difference

Task

You are given two dates, $date1 and $date2 in the format YYYY-MM-DD.

Write a script to find the difference between the given dates in terms on years and days only.

My solutions

This is a little tricky. Date math is never fun. So off the bat, I'll note this is not time zone aware. That really would only be an issue for the few countries that skipped a day in December 2011.

The basic logic goes as follows:

  1. Make sure that date2 is later than date1. The challenge does not mention in what order the date is specified.
  2. Subtract the difference in the calendar years between date2 and date1, and store it as years.
  3. If date2 is earlier in the year than date1, then subtract 1 from the years value.
  4. Calculate the number of days between date2 - $years year(s) and date1. For Python, this is done using the dateutils module. In Perl, I use the Date::Calc module.
  5. Print the result. I'm having a bit of a brain fart on how to do this the correct way. I'm sure after I submit my pull request, I'll figure this out :)

Examples

$ ./ch-2.py 2019-02-10 2022-11-01
3 years 264 days

$ ./ch-2.py 2020-09-15 2022-03-29
1 year 195 days

$ ./ch-2.py 2019-12-31 2020-01-01
1 day

$ ./ch-2.py 2019-12-31 2019-12-01
30 days

Enable GitHub Actions for CI on Math::Polynomial::Chebyshev

Perl Maven

Published by Gabor Szabo on Sunday 25 September 2022 08:30

When looking at the recent uploads to CPAN I bumped into the Math-Polynomial-Chebyshev and noticed it does not have any CI system enabled. So I guess I could contribute to this package a bit by adding GitHub Actions to it.

(cdxi) 12 great CPAN modules released last week

Niceperl

Published by Unknown on Saturday 24 September 2022 23:04

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

  1. Alien::Build - Build external dependencies for use in CPAN
    • Version: 2.70 on 2022-09-23
    • Votes: 22
    • Previous version: 2.68 was 18 days before
  2. App::lcpan - Manage your local CPAN mirror
    • Version: 1.071 on 2022-09-19
    • Votes: 14
    • Previous version: 1.070 was 4 months, 10 days before
  3. App::Netdisco - An open source web-based network management tool.
    • Version: 2.057001 on 2022-09-24
    • Votes: 14
    • Previous version: 2.055001 was 22 days before
  4. DateTime::TimeZone - Time zone object base class and factory
    • Version: 2.54 on 2022-09-24
    • Votes: 18
    • Previous version: 2.53 was 1 month, 10 days before
  5. FFI::CheckLib - Check that a library is available for FFI
    • Version: 0.30 on 2022-09-22
    • Votes: 13
    • Previous version: 0.29 was 12 days before
  6. Future::AsyncAwait - deferred subroutine syntax for futures
    • Version: 0.59 on 2022-09-23
    • Votes: 43
    • Previous version: 0.58 was 4 months, 24 days before
  7. Inline::Python - Write Perl subs and classes in Python.
    • Version: 0.57 on 2022-09-18
    • Votes: 12
    • Previous version: 0.56 was 5 years, 1 month, 14 days before
  8. Module::CoreList - what modules shipped with versions of perl
    • Version: 5.20220920 on 2022-09-21
    • Votes: 38
    • Previous version: 5.20220820 was 1 month, 1 day before
  9. Pithub - Github v3 API
    • Version: 0.01040 on 2022-09-23
    • Votes: 19
    • Previous version: 0.01039 was 1 month, 15 days before
  10. Test::Most - Most commonly needed test functions and features.
    • Version: 0.38 on 2022-09-24
    • Votes: 38
    • Previous version: 0.37 was 2 years, 5 months, 20 days before
  11. Type::Tiny - tiny, yet Moo(se)-compatible type constraint
    • Version: 2.000000 on 2022-09-23
    • Votes: 132
    • Previous version: 1.016010 was 23 days before
  12. Variable::Magic - Associate user-defined magic to variables from Perl.
    • Version: 0.63 on 2022-09-20
    • Votes: 24
    • Previous version: 0.62 was 4 years, 10 months, 16 days before

(dxxiv) metacpan weekly report

Niceperl

Published by Unknown on Saturday 24 September 2022 23:01

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

This week there isn't any remarkable distribution

Build date: 2022/09/24 21:01:22 GMT


Clicked for first time:


Increasing its reputation:

(dlii) stackoverflow perl report

Niceperl

Published by Unknown on Saturday 24 September 2022 23:00

course change for Kephra

blogs.perl.org

Published by lichtkind on Saturday 24 September 2022 15:45

Kephra, an editor for programming (mostly Perl) written in WxPerl is my main project since I stumbled into the Perl community. Most people I know already heard of it - but I want to write about a new development that might be helpful for some, which might consider to use it even if it has a very limited feature set (forth rewrite baby!).


It was silent for some time - because being my main project - I tried to cram all my other ideas, mainly KBOS into it which bogged progress down. Maybe there will be an Object System just for Kephra, solving some issues I saw nowhere else dressed. But for now I'm surprised how much progress is possible, If you just focus on churning out features.

I took stage sed (which is the bare minimal editor I once wrote as proof of concept) and just started to adding features and fixing issues. Sed stands for Single document EDitor and that is all what next release will bring. Am I serious ? and why should you care? Well I'm German - we never joke and it has strengths in its editing capability which sound like - 'duh its an editor - but if you see how many so called Editors and IDE neglect this area while focusing on the big guns like refactoring, debugging and git integration.

But what do I mean with editing is the ability to navigate and shape text as easily as possible. For illustration lets consider the following scenario:

I want to add a sub to a class which is somewhat similar to another already existing. So i skip the subs down in the file by hitting thee times <Ctrl>+<PgDown> and were thereat the start of the sub. To select it its enough to hit <Ctrl>+<Shift>+<Down> twice and we have both blocks which selected - <Ctrl>+<C> obviously copies the selection. Now we have to go back where we were editing - <Ctrl>+<E> - done. And then <Ctrl>+<V> - the sub is pasted and we can start to take what we need from it. The first two line we can discard - <Ctrl>+<X> twice. Yes its the normal cut command but if nothing is selected it cuts the current line, because 1) why waste precious key space (I'm looking at you nano) and 2) as programmers we think in line of code anyway and 3) it's not like we overloaded the command with something radically different. Then the next 3 lines have to move to the end - but to select them from start to end are too much key strokes. So lets just move the cursor into the first line, press <Shift> and <Down> twice. It is enough the selection spans on arbitrary positions over the 3 lines in question. Now hit <Alt> and lets got for a ride Move the line with cursor (<Up> and <Down>) but also <Left> and <Right> the indent and dedent - which is especially handy if you move single lines (which doesn't even needs selection).

Some of the other very simple but deeply practical features are doubling text and rectangular selection to editing several lines at ones. And its the many little details like a search bar that can not cover text like a search dialog. which can be easily extended into replace bar and back. A block comment functions which comments all selected lines with '#~ ' so it doesn't interfere with special comment (which you can still use with another command) and the space at the end of '#~' is also important so you can still read the commented code easily. Its not rocket science but lot of work and eye for details.

Good - now you know what I mean by editing. More features to come and the next stage (1.n releases) will have more than one doc, a little project handling and a config dialog. But let's not get ahead of ourselves again. Kephra is meant to be easy to use, configurable hackable, but for deep feature sets you need integrate specialized tools.

Perl documentation audit project featured at conference

Perl Foundation News

Published by Nic Evans on Saturday 24 September 2022 07:08

Khawar Latif presented the findings of his Google Season of Docs perl documentation audit at the IEEE ProComm 2022 and the conference paper, Documentation in Open-Source Organizations: Content Audit and Gap Analysis for Perl, is now published at IEEExplore.

Khawar said: “Thanks to Jason McIntosh, Makoto Nozaki and Dan Book for their support, and everyone who helped with the project. I hope this helps Perl and Open Source organizations in general.”

My Perl Weekly Challenge

blogs.perl.org

Published by awncorp on Friday 23 September 2022 18:59

Really, how hard could it be?

All this talk about types, objects, and systems, got me to thinking, "what would it take to create a 100% backwards-compatible pure Perl proof-of-concept for optionally typable subroutine signatures". I mean really, how hard could it be? So I started sketching out some ideas and here's what I came up with:

use typing;

sub greet :Function(string, number) :Return() {
  my ($name, $count) = &_;

  print "Hi $name, you have $count messages waiting ...\n";
}

This final sketch felt very Perlish and I had an inkling that I might be able to tie all the concepts being used together, and I did. It actually works, and it's fast. Let's break down what's actually happening here.

use typing;

I don't particularly like or care about the name, I had to call it something, the code is about resolving types, so I called it "typing". When you import the package the framework installs two magic symbols. Oh, yes, btw, once I made it all work, I decided to extend it so that any type or object system could hook into it to allow the resolution of their own types using this system, so yes, it's a framework.

sub greet :Function(string, number) :Return();

The "greet" subroutine is just a plain ole subroutine. No source filter, no Perl keyword API, no XS, no high-magic. Here we're using old school "attributes" to annotate the subroutine and denote whether it's a function or method, and whether it has a return value or not.

sub greet :Method(object, string) :Return(object);

Declaring a subroutine as a method doesn't do anything special. No automagic unpacking, no implied/inferred first argument. The same is true for the "return" declaration. In fact, the annotations aren't involved in the execution of your program unless to you use the magic "unpacker" function.

# use this ...
my ($name, $count) = &_;

# instead of this ...
my ($name, $count) = @_;

This works due to a little-known Perl trick that only the most neck-beardiest of Perl hackers understand, and me, which is what happens when you call a subroutine using the ampersand without any arguments, i.e. you can operate on the caller's argument list. By naming the function _, and requiring the use of the ampersand, we've created a cute little synonym for the @_ variable.

sub greet :Function(string, number) :Return() {
  my ($name, $count) = &_;
  # ...
}

Here's what's happening. The "unpacker" function gets the typed argument list for the calling subroutine, i.e. it gets its signature, then it iterates over the arguments calling the configured validator for each type expression specified at each position in the argument list.

greet() # error
greet({}) # error
greet('bob') # error
greet('bob', 2) # sweet :)

But what happens if you provide more arguments than the signature has type expressions for? The system is designed to use the last type specified to validate all out-of-bounds arguments, which means greet('bob', 2..10) works and passes the type checks, but greet('bob', 2, 'bob', 2) doesn't because the second 'bob' isn't a number. Make sense? Right, but what about the framework bit? First, let's see what it looks like to hook into the framework as a one-off:

use typing;

typing::set_spaces('main', 'main');

sub main::string::make {
  # must return (value, valid?, explanation)
  ($_[0], 1, '')
}

sub greet :Function(string) {
  my ($name) = &_;
  print "Hi $name\n";
}

This example is one of the simplest hooks. The set_spaces function says, the caller is the "main" package, and we should look for types under the "main" namespace by prefixing the type name with "main" and looking for a subroutine called "make". The "make" subroutine must return a list in the form of (value, valid?, explanation). This approach expects each type to correspond to a package (with a "make" routine), but maybe you like the type library/registry approach. Another way to hook into the system is to bring your own resolver:

use typing;

typing::set_resolver('main', ['main', 'resolver']);

sub resolver {
  # accepts (package, type-expr, value)
  # returns (value, valid?, explanation)
  # maybe you'll do something like $registry->get(type-expr)->validate(value)
  ($_[0], 1, '')
}

sub greet :Function(string) {
  my ($name) = &_;
  print "Hi $name\n";
}

This example uses the set_resolver function and says, the caller is the "main" package, and we should resolve all types in the "main" package using the main::resolver subroutine. The resolver must return a list in the form of (value, valid?, explanation). But wait, there's more, ... we can use the framework's API to get the subroutine metadata to further automate our programs, for example:

use typing;

typing::retrieve('main', 'method', 'greet')
# [
#   'MyApp::Object',
#   'string',
#   'number'
# ]

typing::retrieve('main', 'return', 'greet')
# [
#   'MyApp::Object'
# ]

sub greet :Function(MyApp::Object, string, number) :Return(MyApp::Object) {
  # ...
}

I'm supposed to be working on a completely different project right now, but this idea captivated me and so I lost a couple of days of productivity. Maybe others will find this idea interesting. If you're interested in the source code for this concept you can find it here!

Sources

Type libraries

MooseX::Types

Type::Tiny

Specio

Subroutine signatures

Function::Parameters

Method::Signatures

registry/routines

End Quote

"Software is like art and the only justification you need for creating it is, 'because I felt like it'" - Andy Wardley

Authors

Awncorp, awncorp@cpan.org

TPF launches merch store for Perl 5

blogs.perl.org

Published by Dean on Friday 23 September 2022 17:44

TPF has launched an online store with Perl merchandise (swag) celebrating the Perl 5.36 release. The marketing committee plan to do a custom celebratory collection for each release of Perl with revenue from each sale goes to TPF's Perl fund.

The store includes long- and short-sleeved t-shirts, sweatshirts, hoodies and stickers - all featuring a new Raptor image for the 5.36 release.

800.jpga800.jpg

From: https://news.perlfoundation.org/post/tpf-merch-store

My Perl Weekly Challenge

dev.to #perl

Published by Al Newkirk on Friday 23 September 2022 13:49

Really, how hard could it be?

All this talk about types, objects, and systems, got me to thinking, "what would it take to create a 100% backwards-compatible pure Perl proof-of-concept for optionally typable subroutine signatures". I mean really, how hard could it be? So I started sketching out some ideas and here's what I came up with:

use typing;

sub greet :Function(string, number) :Return() {
  my ($name, $count) = &_;

  print "Hi $name, you have $count messages waiting ...\n";
}

This final sketch felt very Perlish and I had an inkling that I might be able to tie all the concepts being used together, and I did. It actually works, and it's fast. Let's break down what's actually happening here.

use typing;

I don't particularly like or care about the name, I had to call it something, the code is about resolving types, so I called it "typing". When you import the package the framework installs two magic symbols. Oh, yes, btw, once I made it all work, I decided to extend it so that any type or object system could hook into it to allow the resolution of their own types using this system, so yes, it's a framework.

sub greet :Function(string, number) :Return();

The "greet" subroutine is just a plain ole subroutine. No source filter, no Perl keyword API, no XS, no high-magic. Here we're using old school "attributes" to annotate the subroutine and denote whether it's a function or method, and whether it has a return value or not.

sub greet :Method(object, string) :Return(object);

Declaring a subroutine as a method doesn't do anything special. No automagic unpacking, no implied/inferred first argument. The same is true for the "return" declaration. In fact, the annotations aren't involved in the execution of your program unless to you use the magic "unpacker" function.

# use this ...
my ($name, $count) = &_;

# instead of this ...
my ($name, $count) = @_;

This works due to a little-known Perl trick that only the most neck-beardiest of Perl hackers understand, and me, which is what happens when you call a subroutine using the ampersand without any arguments, i.e. you can operate on the caller's argument list. By naming the function _, and requiring the use of the ampersand, we've created a cute little synonym for the @_ variable.

sub greet :Function(string, number) :Return() {
  my ($name, $count) = &_;
  # ...
}

Here's what's happening. The "unpacker" function gets the typed argument list for the calling subroutine, i.e. it gets its signature, then it iterates over the arguments calling the configured validator for each type expression specified at each position in the argument list.

greet() # error
greet({}) # error
greet('bob') # error
greet('bob', 2) # sweet :)

But what happens if you provide more arguments than the signature has type expressions for? The system is designed to use the last type specified to validate all out-of-bounds arguments, which means greet('bob', 2..10) works and passes the type checks, but greet('bob', 2, 'bob', 2) doesn't because the second 'bob' isn't a number. Make sense? Right, but what about the framework bit? First, let's see what it looks like to hook into the framework as a one-off:

use typing;

typing::set_spaces('main', 'main');

sub main::string::make {
  # must return (value, valid?, explanation)
  ($_[0], 1, '')
}

sub greet :Function(string) {
  my ($name) = &_;
  print "Hi $name\n";
}

This example is one of the simplest hooks. The set_spaces function says, the caller is the "main" package, and we should look for types under the "main" namespace by prefixing the type name with "main" and looking for a subroutine called "make". The "make" subroutine must return a list in the form of (value, valid?, explanation). This approach expects each type to correspond to a package (with a "make" routine), but maybe you like the type library/registry approach. Another way to hook into the system is to bring your own resolver:

use typing;

typing::set_resolver('main', ['main', 'resolver']);

sub resolver {
  # accepts (package, type-expr, value)
  # returns (value, valid?, explanation)
  # maybe you'll do something like $registry->get(type-expr)->validate(value)
  ($_[0], 1, '')
}

sub greet :Function(string) {
  my ($name) = &_;
  print "Hi $name\n";
}

This example uses the set_resolver function and says, the caller is the "main" package, and we should resolve all types in the "main" package using the main::resolver subroutine. The resolver must return a list in the form of (value, valid?, explanation). But wait, there's more, ... we can use the framework's API to get the subroutine metadata to further automate our programs, for example:

use typing;

typing::retrieve('main', 'method', 'greet')
# [
#   'MyApp::Object',
#   'string',
#   'number'
# ]

typing::retrieve('main', 'return', 'greet')
# [
#   'MyApp::Object'
# ]

sub greet :Function(MyApp::Object, string, number) :Return(MyApp::Object) {
  # ...
}

I'm supposed to be working on a completely different project right now, but this idea captivated me and so I lost a couple of days of productivity. Maybe others will find this idea interesting. If you're interested in the source code for this concept you can find it here!

Sources

Type libraries

MooseX::Types

Type::Tiny

Specio

Subroutine signatures

Function::Parameters

Method::Signatures

registry/routines

End Quote

"Software is like art and the only justification you need for creating it is, 'because I felt like it'" - Andy Wardley

Authors

Awncorp, awncorp@cpan.org

Dancer2: Exercise 3 - Simple Single-user TODO list AP

Perl Maven

Published by Gabor Szabo on Friday 23 September 2022 11:00

Part of the Dancer2 video course.

TPF launches merch store

Perl Foundation News

Published by Nic Evans on Friday 23 September 2022 05:47


TPF has launched an online store with Perl merchandise (swag) celebrating the Perl 5.36 release. The marketing committee plan to do a custom celebratory collection for each release of Perl with revenue from each sale going to TPF's Perl fund.

The store includes long- and short-sleeved t-shirts, sweatshirts, hoodies and stickers - all featuring a new Raptor image for the 5.36 release.

Please share the link via your socials! https://the-perl-store.creator-spring.com/

Class::Plain - Class Syntax for Hash-Based Perl OO

blogs.perl.org

Published by Yuki Kimoto on Friday 23 September 2022 03:45

Class::Plain provides a class syntax for the hash-based Perl OO.

Usage

use Class::Plain;
 
class Point {
  field x;
  field y;
   
  method new : common {
    my $self = $class->SUPER::new(@_);
     
    $self->{x} //= 0;
    $self->{y} //= 0;
     
    return $self;
  }
   
  method move {
    my ($x, $y) = @_;
     
    $self->{x} += $x;
    $self->{y} += $y;
  }
   
  method describe {
    print "A point at ($self->{x}, $self->{y})\n";
  }
}
 
my $point = Point->new(x => 5, y => 10);
$point->describe;

Inheritance:

class Point3D : isa(Point) {
  field z;
   
  method new : common {
    my $self = $class->SUPER::new(@_);
     
    $self->{z} //= 0;
     
    return $self;
  }
   
  method move {
    my ($x, $y, $z) = @_;
     
    $self->SUPER::move($x, $y);
    $self->{z} += $z;
  }
   
  method describe {
    print "A point at ($self->{x}, $self->{y}, $self->{z})\n";
  }
}
 
my $point3d = Point3D->new(x => 5, y => 10, z => 15);
$point3d->describe;

See also the Class::Plain document and the cookbook.

Comment of First Release

Class::Plain was released at 2022-09-22.

I'm strongly interested in Perl OO. I study Corinna and Object::Pad now.

A few weaks ago, I wondered "These class syntax can be applied to the traditional Perl hash-based OO modules. The syntax can be used with the all existing modules".

I remembered many OO modules. Net::FTP, IO::Socket::INET, IO::Socket::IP, LWP::UserAgent, HTTP::Tiny, XML::Simple, Data::Page, CGI, Digest::MD5, Digest::SHA, Mojolicious, Catalyst, DBIx::Class etc .

And the existing modules for OO. Moo/Moose, Mojo::Base, Class::Accessor, Class::Accessor::Fast.

"Is my assumption correct?" I tried to create a module it was called Class::Plain.

I copied Object::Pad, and reduced the code except for the class, field, method keywords, and the internal data structure is changed from lexical variables to a hash reference(This contains a little lie because the hash reference is created dynamically).

And I completed the implementation of Class::Plain and released it to CPAN.

Comments are welcome!


Class::Plain - Class Syntax for Hash-Based Perl OO

dev.to #perl

Published by Yuki Kimoto on Thursday 22 September 2022 22:56

Class::Plain was released at 2022-09-22.

use Class::Plain;

class Point {
  field x;
  field y;

  method new : common {
    my $self = $class->SUPER::new(@_);

    $self->{x} //= 0;
    $self->{y} //= 0;

    return $self;
  }

  method move {
    my ($x, $y) = @_;

    $self->{x} += $x;
    $self->{y} += $y;
  }

  method describe {
    print "A point at ($self->{x}, $self->{y})\n";
  }
}

my $point = Point->new(x => 5, y => 10);
$point->describe;

Inheritance:

class Point3D : isa(Point) {
  field z;

  method new : common {
    my $self = $class->SUPER::new(@_);

    $self->{z} //= 0;

    return $self;
  }

  method move {
    my ($x, $y, $z) = @_;

    $self->SUPER::move($x, $y);
    $self->{z} += $z;
  }

  method describe {
    print "A point at ($self->{x}, $self->{y}, $self->{z})\n";
  }
}

I'm strongly interested in Perl OO. I study Corinna and Object::Pad now.

A few weaks ago, I wondered "These class syntax can be applied to the traditional Perl hash-based OO modules. The syntax can be used with the all existing modules".

I remembered many OO modules. Net::FTP, IO::Socket::INET, IO::Socket::IP, LWP::UserAgent, HTTP::Tiny, XML::Simple, Data::Page, CGI, Digest::MD5, Digest::SHA, Mojolicious, Catalyst, DBIx::Class etc .

Class::Plain - Class Syntax for Hash-Based Perl OO

Thank you Japan Perl Association

Perl Foundation News

Published by Nic Evans on Thursday 22 September 2022 11:27

Japan Perl Association (JPA) came up with an innovative idea to raise money for The Perl Foundation from their annual event, YAPC::Japan.

To promote the online 2022 YAPC::Japan conference, the organizers chose to donate to TPF 5 yen per tweet that included #yapcjapan, and 300 yen per blog. Contributors raised 15,630 yen (just over US$100). What a great way to raise money and also to raise awareness of their event.

We understand JPA is planning an in person conference in Kyoto March 2023. Watch this space.

Thank you Japan Perl Association!

Named Subroutine Arguments in Perl

dev.to #perl

Published by Nicholas Hubbard on Thursday 22 September 2022 01:13

Naming your subroutine arguments has benefits around increasing the readability of your code. Lets look at an example of code that can benefit from named arguments:

sub safe_open {

    my $file = shift @_;
    my $mode = shift @_;
    my $die_on_failure = shift @_;

    my $success = open(my $fh, $mode, $file);

    if ((not $success) and $die_on_failure) {
        die "error: failed to open '$file': $!\n";
    }

    return $fh;
}

In the following examples we can see that the third argument allows us to control if we should kill the program if the file cannot be opened:

my $fh = safe_open('/file/that/doesnt/exist', '>', 1);
print $fh "Hello, World!\n";

# OUTPUT:
# error: failed to open '/file/that/doesnt/exist': No such file or directory
my $fh = safe_open('/file/that/doesnt/exist', '>', 0);
print $fh "Hello, World!\n";

# OUTPUT:
# print() on closed filehandle $fh at ./scratch.pl line 22.

Imagine if somebody who has never worked with this code before comes across these calls to &safe_open. It will be impossible for them to know what the third argument stands for unless they go and look at the actual code of the subroutine.

To make it easier for people to understand the meaning of the arguments, we can name them!

sub safe_open {

    my %args = (
        FILE => '',
        MODE => '',
        DIE_ON_FAILURE => 1,
        @_
    );

    $args{FILE} or die "error: missing FILE arg in call to &safe_open\n";
    $args{MODE} or die "error: missing MODE arg in call to &safe_open\n";

    my $success = open(my $fh, $args{MODE}, $args{FILE});

    if ((not $success) and $args{DIE_ON_FAILURE}) {
        die "error: failed to open '$args{FILE}': $!\n";
    }

    return $fh;
}

Lets look at some examples of calling this subroutine:

my $fh = safe_open(FILE => '/file/that/doesnt/exist', MODE => '>', DIE_ON_FAILURE => 1);
print $fh "Hello, World!\n";

# OUTPUT:
# error: failed to open '/file/that/doesnt/exist': No such file or directory
my $fh = safe_open(FILE => '/file/that/doesnt/exist', MODE => '>');
print $fh "Hello, World!\n";

# OUTPUT:
# error: failed to open '/file/that/doesnt/exist': No such file or directory
my $fh = safe_open(DIE_ON_FAILURE => 0, FILE => '/file/that/doesnt/exist', MODE => '>');
print $fh "Hello, World!\n";

# OUTPUT:
# print() on closed filehandle $fh at ./scratch.pl line 25.

There are a few things to note from these examples.

  • The arguments must be explicitly named using ARG => value syntax.
  • The argument order does not matter.
  • The DIE_ON_FAILURE argument is optional and defaults to true.

Our &safe_open subroutine has these features because of the strategy used for constructing the %args hash.

The reason the argument order doesn't matter is because hashes are unordered and in the end we are constructing a hash out of the argument list.

An array can be used to construct a hash as long as it has an even number of elements. We leverage this to use the @_ array to construct the %args hash. Here is an example of this behavior:

my @array = ('foo', 12, 'bar', 13);

my %hash = @array;

print "\$hash{'foo'} = $hash{'foo'}\n";
print "\$hash{'bar'} = $hash{'bar'}\n";

# OUTPUT:
# $hash{'foo'} = 12
# $hash{'bar'} = 13

We are able to give default argument values because of the fact that, if a hash definition defines the same key multiple times, then the last definition is used. If the user leaves off an argument, then it is not redefined and stays set to the default. Consider this example:

my %hash = (
    FOO => 12,
    FOO => 13
);

print "\$hash{'FOO'} = $hash{'FOO'}\n";

# OUTPUT:
# $hash{'FOO'} = 13

Synopsis

We can use the subroutines argument array (@_) to construct a hash, which can give us significant benefits in terms of code readability. By constructing a hash from the argument array, all calls to the subroutine must explicitly name their arguments the argument order becomes irrelevant, and arguments can be given default values.

Maintaining Perl (Tony Cook) August 2022

Perl Foundation News

Published by alh on Wednesday 21 September 2022 09:59


Tony writes:

``` [Hours] [Activity] 2022/08/01 Monday 0.17 #20005 review fixes 1.45 #19943 review, try to break and approve 0.72 #20008 review

1.17 #19964 work on ppport updates

3.51

2022/08/02 Tuesday 1.18 #19964 more ppport 1.33 #19964 more ppport 1.22 #19888 look at CI testing upstream blead modules on old

perls

3.73

2022/08/03 Wednesday 2.52 #19888 more module CI testing 1.85 #19888 more module CI testing, try to test with threaded

perls

4.37

2022/08/04 Thursday 1.23 #19931 research

1.37 #19888 module CI testing working, start on cleanup

2.60

2022/08/08 Monday 0.93 #19946 research and comment 0.20 #20064 review and approve 0.47 #20055 review and comments 0.75 #20033 review, research and comment 0.47 #19993 consider possible other optimizations 0.18 #20005 review and comment 1.18 #19888 squash some commits and push for CI, work on

integrating working workflow into the base testsuite.yml

4.18

2022/08/09 Tuesday 0.27 review github notifications 1.15 #20060 try a fix, testing, comment 0.10 #20033 follow-up comment 0.02 #20055 review latest changes and approve 2.10 #19888 yaml struggle time, get it working, porting fixes,

rebase and cleanup, push for (hopefully) final CI

3.64

2022/08/10 Wednesday 0.45 review github notifications 0.40 #19888 review CI results and open PR #20006 0.27 #20068 review and comment 0.67 #20052 review and brief comments 0.45 #20044 review and approve 0.12 #20074 follow-up 0.12 #20068 follow-up, check if some of the code is warning (it wasn’t) 1.48 look into many warnings generated on cygwin, debug

initialization crash

3.96

2022/08/11 Thursday 2.87 more cygwin, debugging, make a reproducer, test code supplied by khw, report to cygwin mailing list, test another candidate 0.10 #20079 review discussion 0.55 #20074 update commit messages, testing, comment 0.28 #20068 review latest changes and approve 0.07 #20076 review latest changes and approve

0.38 #20052 more review and comment

4.25

2022/08/12 Friday 0.08 cygwin: follow-up response to list 0.88 #20074 review comments and make changes to reflect some of

them

0.96

2022/08/15 Monday 0.67 testing, respond to message from bram about deps I added to win32/Makefile long ago 1.22 #19851 testing 1.98 #19851 only one error, look into it, work on a fix,

testing, push for CI

3.87

2022/08/16 Tuesday 0.67 #20033 review and comment 0.47 #20060 try to track down cause of failing test 1.42 #20060 more track down, find cause, re-work test, testing, push for CI

0.08 #19851 check CI results, open PR #20094

2.64

2022/08/17 Wednesday 0.15 #20060 check CI results, open PR #20103 0.62 #20100 review, research and comment 0.72 #20037 comment 0.15 #20102 review and approve 1.87 review class feature code, add a couple of assertion

failures to the discussions

3.51

2022/08/18 Thursday 1.88 #20103 respond to comment, add tests 0.48 #20111 review and approve

1.13 more review class feature code

3.49

2022/08/22 Monday 0.88 github notifications 1.42 #20103 research, work on changes, testing 0.52 #20103 cleanup, push to update PR, comment

1.48 #19857 work on a fix

4.30

2022/08/23 Tuesday 0.23 github notifications 0.25 #20133 review 0.97 #20133 more review, try to understand the problem, testing, approve 1.40 #19857 work on a possible fix, fixes assert, but sub not

found at eval runtime

2.85

2022/08/24 Wednesday 0.27 github notifications 0.72 #20033 review, testing, comment 0.42 #20144 review discussion, research and comment

1.67 #19857 debugging, testing, comment

3.08

2022/08/25 Thursday 0.40 #20144 follow-up 0.28 #20037 consider whether recursion can break this 0.53 #20033 review latest changes and apply to blead 0.55 #20144 try to reproduce undefined symbol error, reproduce 0.58 #20144 track down cause and comment

0.88 #19857 testing, work on commit message

3.22

2022/08/28 Sunday

0.13 #20169 review and approve

0.13

2022/08/29 Monday 0.68 class feature code: open leonerd/perl5/issues/21 0.18 github notifications 1.17 #19857 refactor, push for CI 0.63 #20177 review and comments 1.32 #20143 review, try to demonstrate a problem on Win32,

build error with vs2022, build ok with 2019

3.98

2022/08/30 Tuesday 1.00 #20143 testing 0.50 #20143 comment, try to reproduce build failure with updated vs2022 and fail 0.95 #20185 review, realise related issue and create issue

20189

2.45

2022/08/31 Wednesday 0.30 #20103 apply to blead, perldelta 0.10 #20074 apply to blead (I don’t think it needs it’s own perldelta) 0.20 look into build warning and fix 0.10 #19857 check CI results, make PR #20199 0.20 #20186 research, comment 0.27 #20185 review and approve 0.08 #20183 briefly comment 0.67 #20181 review and approve

1.05 #20179 review, testing, debugging and comment

2.97

Which I calculate is 67.69 hours.

Approximately 35 tickets were reviewed or worked on, and 3 patches were applied. ```

Read section of a file

Perl Maven

Published by Gabor Szabo on Tuesday 20 September 2022 10:15

I was working on an example script that used a lot of calls to seek, but I kept bumping into bugs. I thought it might be a useful debugging tool to be able to read and print any section of a file given the location of the first byte and the number of bytes.

So here is a quick script I put together.

Types, Objects, and Systems, Oh my!

dev.to #perl

Published by Al Newkirk on Monday 19 September 2022 20:12

Inextricably bound

Perl isn't a strongly typed language, and its built-in types are limited and not generally accessible to the engineer, however, Perl supports various classes of data and in recent years has flirted with various ways of enabling runtime type checking.

In a strongly typed language the tl;dr; case for declaring data types is memory management, compile-time code optimization, and correctness. To this day I'm both impressed and horrified by the number of errors caught when I implement some kind of type checking in my programs. When it comes to runtime type checking we're only concerned with enforcing correctness.

Types, values, objects, signatures, and the systems that tie these all together, are all inextricably bound. They are necessarily interdependent in order to present/provide a cohesive and consistent system. Peeling back the layers a bit, types are merely classifications of data. Any given piece of data can be classified as belonging to a particular type whether implicit or explicit.

Types are instantiated (i.e. have concrete representations, i.e. instances) whenever data is created and/or declared as conforming to the type's criteria. Runtime types are arbitrary. A value of 1 can be said to be of type number where the value "1" can be said to be of the type string. Also in Perl, an object is a specific kind of reference; a reference tied to a particular namespace.

Runtime type libraries

Currently, as per the CPAN, there are a few different ways to declare and use runtime type checking in your application. The three most popular libraries, in no particular order, are, MooseX::Types, Type::Tiny, and Specio. All of these type libraries have Moo/se compatibility as their stated goal.

MooseX::Types (2009) was designed to address the Moose global registry (and type conflict) problem.

package MyLibrary;

use MooseX::Types -declare => [
  'PositiveInt',
  'NegativeInt',
];

use MooseX::Types::Moose 'Int';

subtype PositiveInt,
  as Int,
  where { $_ > 0 },
  message { "Int is not larger than 0" };

subtype NegativeInt,
  as Int,
  where { $_ < 0 },
  message { "Int is not smaller than 0" };

1;

Type::Tiny (2013), inspired by MooseX::Types, was designed to have a small footprint, a single non-core dependency, a set of "core" types as a standard library, and to have first-class support for use with Moo.

package MyLibrary;

use Type::Library -base;
use Type::Utils -all;

BEGIN { extends "Types::Standard" };

declare 'PositiveInt',
  as 'Int',
  where { $_ > 0 },
  message { "Int is not larger than 0" };

declare 'NegativeInt',
  as 'Int',
  where { $_ < 0 },
  message { "Int is not smaller than 0" };

1;

Specio (2013) is meant to be a replacement for Moose's built-in types, MooseX::Types, and the Moose global registry (and type conflict) problem.

package MyLibrary;

use Specio::Declare;
use Specio::Library::Builtins;

declare(
  'PositiveInt',
  parent => t('Int'),
  where  => sub { $_[0] > 0 },
  message_generator => sub { "Int is not larger than 0" },
);

declare(
  'NegativeInt',
  parent => t('Int'),
  where  => sub { $_[0] < 0 },
  message_generator => sub { "Int is not smaller than 0" },
);

1;

What these libraries have in common is the concept of declaring custom types using a DSL and organizing and exporting types from one or more registries. They also (in practice) produce registries that act as exporters that litter the calling package with use-once functions which require namespace::autoclean to get rid of. To be fair, both Type-Tiny and Specio have object-oriented interfaces that allow you to build types and registries without using the DSL.

Introducing Venus::Assert

Meet Venus::Assert, a simple data type assertion class that could serve as the foundation for a future object-oriented type assertion and coercion system for Perl 5.

Venus, the non-core object-oriented standard library, by necessity needs to be able to distinguish between different types of data. It's how the library is capable of distinguishing between the number 1, the string 1, and the conventional boolean 1.

Venus::Assert wraps that know-how in an intuitive utility class that behaves in the tradition of its siblings and provides the foundations for a future Venus-based unified type checking system.

Because Venus::Assert is a Venus utility class it can, without any additional code, complexity, or effort, throw itself, catch itself, try itself, etc.

Throws itself

Venus::Assert->new('PositiveNum')->number(sub{$_->value > 0})->throw;

Catches itself

my ($result, $error) = Venus::Assert->new('NegativeNum')->number(sub{$_->value < 0})->catch('validate', $value);

Tries itself

my $tryable = Venus::Assert->new('PositiveNum')->number(sub{$_->value > 0})->try('validate', $value);

Venus::Assert doesn't have a DSL, doesn't support or encourage type registries, doesn't concern itself with inlining, and doesn't declare parent types to be extended. Venus::Assert instances are simple code-convertible objects built on Venus::Match for powerful object-oriented case/switch operations. Code-convertible custom types can be declared as plain ole packages which conform to a particular interface:

package MyApp::Type::PositiveNumber;

use base 'Venus::Assert';

sub conditions {
  my ($self) = @_;

  $self->number(sub{$_->value > 0});
}

1;

Extending custom types with proper names and explanations (on failure) by doing something like the following:

package MyApp::Type::PositiveNumber;

use base 'Venus::Assert';

sub name {
  my ($self) = @_;
  return $self->class;
}

sub message {
  my ($self) = @_;
  return 'Type assertion (%s) failed, expects a number > 0, received (%s)';
}

sub conditions {
  my ($self) = @_;
  return $self->number(sub{$_->value > 0});
}

Types::Standard via Venus::Assert

We could easily use Venus::Assert to approximate 90% of what the Type::Tiny Types::Standard library does, with a few lines of code. For example:

Any

Venus::Assert->new->any

... or

Venus::Assert->new(on_none => sub{true})

Bool

Venus::Assert->new->boolean

Maybe[a]

Venus::Assert->new->maybe($a)

... or

Venus::Assert->new->maybe->$a

... or

Venus::Assert->new->undef->$a

Undef

Venus::Assert->new->undef

Defined

Venus::Assert->new->defined

... or

Venus::Assert->new->when(sub{defined $_->value})->then(sub{true})

Value

Venus::Assert->new->value

... or

Venus::Assert->new->when(sub{defined $_->value && !ref $_->value})->then(sub{true})

Str

Venus::Assert->new->string

Num

Venus::Assert->new->number

ClassName

Venus::Assert->new->package

... or

Venus::Assert->new->string->constraints->where->defined(sub{
  Venus::Space->new($_->value)->loaded
})

Ref[a]

Venus::Assert->new->reference

... or

Venus::Assert->new->defined(sub{
  ref($_->value) eq $a
})

ScalarRef[a]

Venus::Assert->new->scalar

... or

Venus::Assert->new->scalar(sub{
  Venus::Assert->new->$a->check($_->value)
});

ArrayRef[a]

Venus::Assert->new->array

... or

Venus::Assert->new->array(sub{
  Venus::Assert->new->$a->check($_->value)
});

HashRef[a]

Venus::Assert->new->hash

... or

Venus::Assert->new->array(sub{
  Venus::Assert->new->$a->check($_->value)
});

CodeRef

Venus::Assert->new->code

RegexpRef

Venus::Assert->new->regexp

GlobRef

Venus::Assert->new->reference(sub{ref $_->value eq 'GLOB'})

Object

Venus::Assert->new->object

Tuple[a]

Venus::Assert->new->tuple(@a)

InstanceOf[a]

Venus::Assert->new->identity($a)

ConsumerOf[a]

Venus::Assert->new->consumes($a)

HasMethods[a]

Venus::Assert->new->routines(@a)

StrMatch[a]

Venus::Assert->new->string(sub{
  $_->deduce->contains($a)
})

Enum[a]

Venus::Assert->new->enum(@a)

The state of the art

Again, types, objects, signatures, and systems, are inextricably bound which means that a good system will provide both architecture and abstractions to support interoperability, or at least declare its way as the one true way. What we have today is an assortment of libraries that tackle a particular aspect of the "runtime type checking" system. Your mileage may vary with regard to interoperability.

Moo/se allows you to type constrain class attributes using MooseX::Types, Type::Tiny, and/or Specio, etc. Moose (last time I check) uses a single global type registry and isn't designed to play nice with others. Moo, to its credit, provides a simple system-agnostic interface, i.e. accepts code-convertible values, which Type::Tiny takes full advantage of. Type::Tiny goes through some pains (IMHO) to make itself Moose-aware and interoperable. None of these libraries prescribed a methodology for reusing the declared types in function/method signatures. Method::Signatures provides function and method signatures but only supports Moose types (as per its global registry). Function::Parameters goes a bit further and does provide an abstraction for hooking into the type resolution mechanism as well as the ability to use local functions in signature type notations.

The Perl "signatures" feature provided bare-bones untyped/untypable signatures, and is little more than syntactic sugar for argument unpacking. The registry/routines pragmas attempt to bring together Function::Parameters and Type::Tiny to provide a unified system for runtime type checking. All of the type libraries support parameterized type declarations, and yet none of the signature pragmas/parsers do.

The future, hopefully

To have proper compile-time types (which are extendable), they need to be built into the language, in which case you'll likely end up with something like Raku.

To have proper runtime types which feel natural and legit in Perl 5 we need to nail the interoperability problem, and to do that we need to devise a standard that allows systems to cooperate.

We need package fields, objects, properties, values, and subroutine signatures to be capable of using the same vocabulary and type notation to declare type constraints, thus recognizing and accepting the same types and data.

Here's an idea

Simple architecture:

  • A type is simply a package with "check" and "make" routines
  • The "check" routine accepts any value and returns a tuple, i.e. (valid?, explanation)
  • The "make" routine accepts any value and returns the value (possibly modified) and the result of the "check" routine, i.e. a tuple of (value, valid?, explanation)
  • A "types" statement, appends the currently scoped @TYPES global, allowing the use of shortnames when referring to types
  • The "type" function accepts a string-based type expression, and any value, resolving the type expression and executing the type's "make" function

Declare custom type

package MyApp::Type::String;

sub check {
  my ($value) = @_;
  (false, 'Not a string')
}

sub make {
  my ($value) = @_
  ($value, check($value));
}

1;

Resolve custom type

package MyApp;

use the-idea-materialized;

types 'MyApp::Type';

my ($value) = type('String', 'hello');

1;

Governance rules and notation:

  • No parameterized types
  • Type resolution fallback to some "core" namespace if local @TYPES global is empty

Sources

Object-systems

Moo

Moose

Type libraries

MooseX::Types

Type::Tiny

Specio

Type::Library

Types::Standard

Subroutine signatures

Function::Parameters

Method::Signatures

registry/routines

End Quote

"Check yo' self before you wreck yo' self" - Ice Cube

Authors

Awncorp, awncorp@cpan.org

Things I learned at PGDay Austria

domm (Perl and other tech)

Published on Monday 19 September 2022 16:42

On Friday 16th the third PGDay Austria took place in Vienna. PGday is a single day PostgreSQL conference with a German and an English track. As I'm using Postgres as my preferred database engine, and also on our most recent project I decided (on rather short notice) to attend.

Here's what I learned:

  • Everybody suffers from the knapsack problem, even if you don't know what it is
    • Francesco Tisiot used this problem (i.e. packing stuff into your backpack) to give a nice introduction to recursive queries
    • He has been "fighting against the Excel lobby" for too long (I hear you!)
    • Besides the hand-drawn images I found it amusing how the font size of the SQL got smaller during the talk
    • Postgres 14 has a few nice optimisations (SEARCH, CYCLE)
  • There are a lot of useful Postgres extensions already in contrib (so no need to install extra stuff)
    • Even after 20 years of giving talks, Hans-Jürgen Schönig is not safe from projector problems. But having some experience makes it less stressful for the speaker and fun for the audience...
    • pg_stat_statements is a must-have
    • "The reason for performance problems is always a query" (so logging query stats helps!)
    • Use citext for case insensitive searches with very little overhead. But: "a little overhead is still better than no result"
    • pg_trgrm for similarity matching using trigrams. Can also be indexed (... USING GIST(col gist_trgm_ops))
    • copy from program seems nice (though dangerous)
    • More to check out: pgstattuple, pg_qualstats
  • There is a lot of Open Data available
    • Unfortunately a lot if it is in not very usable formats, lacking docs, or can currently only be understood by humans
    • Karen Jex is working on a way to Unlock Open Data using an Open Source Database
    • There is a site called findaphd.com (not I have anything to do with academia)
    • It's pity we have to spend so much time on figuring out what each open data set means. If only the authors would have spend a little more time to properly document / annotate the data...
  • One can use pg_hint_plan for further insights into and hints to the query planer
    • I haven't had any need for that yet.
    • But it's nice that you can use unicode characters for table aliases: select 🍎.name,🍌.price from apple as 🍎 left join banana as 🍌 ...
  • Postgres has a some / a lot pitfalls
    • schema public is quite public, so (for postgres < 15) do revoke all on schema public from public;
    • the hba in pg_hba.conf stands for Host Based Access (I was wondering about that for a long time, but always to lazy to look it up..)
    • better use scram-sha-256 than md5 in that file
    • bigserial probably makes more sense than serial (IIRC we were using bigserial in a rather old project, but I stopped using it for recent ones, no idea why..)
  • The Strategies for optimizing materialized views for speed and timeliness seem to mostly apply to TimescaleDB
    • which looks interesting and I wanted to check it out for some time now
    • REFRESH MATERIALIZED VIEW CONCURRENTLY will probably still be useful.
    • Another interesting extension: pg_cron
  • I did not find the keynotes especially interesting
    • They where mostly sponsor presentations, not the weird masterpieces of talks I'm used to from Perl conferences.
    • But still, fair enough to give the sponsors some time to present themselves
  • I did not like the hat in the goodie bag (seems a bit wasteful, and the design will prevent any non-ironic use)
  • Besides that it was another very nice conference!

Thanks to the orgas, speakers, sponsors and attendees!

Dancer2: Before and After Hooks

Perl Maven

Published by Gabor Szabo on Monday 19 September 2022 10:27

Part of the Dancer2 video course.

#582 - Grandfather’s Perl

Perl Weekly

Published on Monday 19 September 2022 10:00

Hi there,

Few months ago, there was a blog post Why Perl is still relevant in 2022 created a lot of noise among the Perl community. The author clearly missed the point. If you check the comments section, you can see how, White Camel Awardee, Dave Cross and few others responed to the post.

I was pleasantly surprised when I found out that Dave came up with perfect response to the other blog post with this This is not your grandfather’s Perl. It has already created positive noise. If you want to take a closer look at the recent changes to the latest release of Perl v5.36 then please do checkout the GitHub repository sharing the changes with example. By the way, it is not just limited to v5.36. You will find plenty more to keep you busy.

Talking about Perl, we got another gem from Curtis Poe sharing the Current Corinna Status. If you can't wait for Corinna, I would suggest you take a look at CPAN module Object::Pad by Paul Evans.

Last but not the least, today, Monday 19 September, the date of Her Majesty Queen Elizabeth II's State Funeral declared as National Bank Holiday. Please checkout the rest of the newsletter.

Deepest Common Index

RabbitFarm Perl

Published on Sunday 18 September 2022 20:17

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

Part 1

You are given a list of integers. Write a script to find the index of the first biggest number in the list.

Solution


use v5.36; 
use strict;
use warnings;

sub index_biggest{
    my(@numbers) = @_;
    my @sorted = sort {$b <=> $a} @numbers; 
    map { return $_ if $numbers[$_] == $sorted[0] } 0 .. @numbers - 1; 
}

MAIN:{
    my @n;
    @n = (5, 2, 9, 1, 7, 6);
    print index_biggest(@n) . "\n";  
    @n = (4, 2, 3, 1, 5, 0);  
    print index_biggest(@n) . "\n";  
}

Sample Run


$ perl perl/ch-1.pl
2
4

Notes

Essentially this solution is two lines, and could even have been a one liner. All that is required is to sort the array of numbers and then determine the index of the first occurrence of the largest value from the original list. Finding the index of the first occurrence can be done using a map with a return to short circuit the search as soon as the value is found.

Part 2

Given a list of absolute Linux file paths, determine the deepest path to the directory that contains all of them.

Solution


use v5.36;
use strict;
use warnings;

sub deepest_path{
    my(@paths) = @_;
    my @sub_paths = map { [split(/\//, $_)] } @paths; 
    my @path_lengths_sorted = sort { $a <=> $b } map { 0 + @{$_} } @sub_paths;    
    my $deepest_path = q//; 
    for my $i (0 .. $path_lengths_sorted[0] - 1){
        my @column =  map { $_->[$i] } @sub_paths;
        my %h;
        map { $h{$_} = undef } @column;
        $deepest_path .= (keys %h)[0] . q#/# if 1 == keys %h;  
    }  
    chop $deepest_path;
    return $deepest_path;  
}

MAIN:{
    my $data = do{
        local $/;
        <DATA>; 
    };
    my @paths = split(/\n/, $data);  
    print deepest_path(@paths) . "\n"; 
}

__DATA__
/a/b/c/1/x.pl
/a/b/c/d/e/2/x.pl
/a/b/c/d/3/x.pl
/a/b/c/4/x.pl
/a/b/c/d/5/x.pl

Sample Run


$ perl perl/ch-2.pl
/a/b/c

Notes

The approach here is fairly straightforward but I will admit that it may look more complex than it truly is if you simply glance at the code.

To summarize what is going on here:

  • We read in the file paths, one path (string) per line.
  • The paths are sent to deepest_path() where we create a 2d array. Each array element is an array reference of file sub paths. For example here $sub_paths[0] is [a, b, c, 1, x.pl].
  • We sort the lengths of all the sub path array references to know how far we must search. We need only look as far as the shortest path after all.
  • At each iteration we take column wise slices.
  • For each column wise slice we check if all the sub paths are equal. We do this but putting all the sub path values into a hash as keys. If we have only one key value when done we know all the values are equal.
  • As long as tall the sub paths are equal we accumulate it in $deepest_path.
  • $deepest_path is returned when we are doing examining all sub paths. (We chop the trailing /). Done!

References

Challenge 182

Colin Crain › Perl Weekly Review #176

The Weekly Challenge

Published on Monday 19 September 2022 00:00

( …continues from previous week. ) Welcome to the Perl review pages for Week 176 of The Weekly Challenge! Here we will take the time to discuss the submissions offered up by the team, factor out some common methodologies that came up in those solutions, and highlight some of the unique approaches and unusual code created. ●︎ Why do we do these challenges? I suppose any reasonable answer to that question would come from a field as wide ranging and varied as the people who choose to join the team.

(cdx) 9 great CPAN modules released last week

Niceperl

Published by Unknown on Saturday 17 September 2022 22:22

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

  1. Devel::IPerl - Perl language kernel for Jupyter
    • Version: 0.012 on 2022-09-14
    • Votes: 21
    • Previous version: 0.011 was 8 months, 21 days before
  2. Exporter::Tiny - an exporter with the features of Sub::Exporter but only core dependencies
    • Version: 1.004002 on 2022-09-16
    • Votes: 21
    • Previous version: 1.004001 was 7 days before
  3. HTTP::BrowserDetect - Determine Web browser, version, and platform from an HTTP user agent string
    • Version: 3.37 on 2022-09-15
    • Votes: 22
    • Previous version: 3.36 was 15 days before
  4. JSON::MaybeXS - Use Cpanel::JSON::XS with a fallback to JSON::XS and JSON::PP
    • Version: 1.004004 on 2022-09-17
    • Votes: 46
    • Previous version: 1.004003 was 1 year, 10 months, 4 days before
  5. Mojolicious - Real-time web framework
    • Version: 9.27 on 2022-09-12
    • Votes: 475
    • Previous version: 9.26 was 3 months, 20 days before
  6. OpenAPI::Client - A client for talking to an Open API powered server
    • Version: 1.06 on 2022-09-11
    • Votes: 15
    • Previous version: 1.05 was 25 days before
  7. Regexp::Grammars - Add grammatical parsing features to Perl 5.10 regexes
    • Version: 1.058 on 2022-09-15
    • Votes: 36
    • Previous version: 1.057 was 2 years, 3 months, 24 days before
  8. Starman - High-performance preforking PSGI/Plack web server
    • Version: 0.4016 on 2022-09-13
    • Votes: 111
    • Previous version: 0.4015 was 3 years, 3 months, 23 days before
  9. YAML::LibYAML - Perl YAML Serialization using XS and libyaml
    • Version: 0.85 on 2022-09-12
    • Votes: 46
    • Previous version: 0.84 was 9 days before

(dxxiii) metacpan weekly report - app::paperback

Niceperl

Published by Unknown on Saturday 17 September 2022 22:20

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

Week's winner: app::paperback (+2)

Build date: 2022/09/17 20:19:14 GMT


Clicked for first time:


Increasing its reputation:

#581 - What to write about?

Perl Weekly

Published on Monday 12 September 2022 10:00

Hi there!

People often tell me that they don't know what to write about or that they are too new to Perl to blog about anything. Let's see.

Last week I posted this article about ANSI command line colors with Perl. It hardly has anything to do with Perl, but I needed it and it can be a useful to others as well. Actually it originated from a discussion I had with my son who is using Python. So first I wrote the article ANSI colors using Python and only after that I converted it to Perl.

It did not require any deep knowledge, definitely not that of Python or Perl.

So if you would like to try writing articles, there are plenty of such small subjects one can cover.

After including the link in the previous edition of the Perl Weekly, Thomas Köhler contacted me saying that he would do it differently and then he posted a short article showing how would he use ANSI colors in Perl including a link back to the original article.

This is excellent.

So here is a suggestion: If you don't have an idea for an article, pick one of the Perl Maven posts and write a different solution or extend the subject and send a link to us, the editors of the Perl Weekly.

Enjoy your week!

These Sentences Are Getting Hot

RabbitFarm Perl

Published on Sunday 11 September 2022 08:45

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

Part 1

You are given a paragraph. Write a script to order each sentence alphanumerically and print the whole paragraph.

Solution


use v5.36;
use strict;
use warnings;

sub sort_paragraph{
    my($paragraph) = @_;
    my @sentences = split(/\./, $paragraph); 
    for(my $i = 0; $i < @sentences; $i++){
        $sentences[$i] = join(" ", sort {uc($a) cmp uc($b)} split(/\s/, $sentences[$i]));
    }
    return join(".", @sentences);
}

MAIN:{
    my $paragraph = do{
        local $/;
        <DATA>;
    };
    print sort_paragraph($paragraph);
}

__DATA__
All he could think about was how it would all end. There was
still a bit of uncertainty in the equation, but the basics
were there for anyone to see. No matter how much he tried to
see the positive, it wasn't anywhere to be seen. The end was
coming and it wasn't going to be pretty.

Sample Run


$ perl perl/ch-1.pl
about All all could end he how it think was would. a anyone basics bit but equation, for in of see still the the There there to uncertainty was were. anywhere be he how it matter much No positive, see seen the to to tried wasn't. and be coming end going it pretty The to was wasn't

Notes

This code is fairly compact but not at all obfuscated, I would argue. First we take in the paragraph all at once. Then we split into sentences and begin the sorting.

The sort is a little complicated looking at first because we want the words to be sorted irrespective of letter case. One way to handle that is to compare only all uppercase versions of the words. Lowercase would work too, of course!

Part 2

You are given file with daily temperature record in random order. Write a script to find out days hotter than previous day.

Solution


use v5.36;
use strict;
use warnings;

use DBI;
use Text::CSV;
use Time::Piece;

sub hotter_than_previous{
    my($data) = @_;
    my @hotter;
    my $csv_parser = Text::CSV->new();
    my $dbh = DBI->connect(q/dbi:CSV:/, undef, undef, undef);
    $dbh->do(q/CREATE TABLE hotter_than_previous_a(day INTEGER, temperature INTEGER)/);
    $dbh->do(q/CREATE TABLE hotter_than_previous_b(day INTEGER, temperature INTEGER)/);
    for my $line (@{$data}){
        $line =~ tr/ //d;
        $csv_parser->parse($line);
        my($day, $temperature) = $csv_parser->fields();
        $day = Time::Piece->strptime($day, q/%Y-%m-%d/);
        $dbh->do(q/INSERT INTO hotter_than_previous_a VALUES(/ . $day->epoch . qq/, $temperature)/);
        $dbh->do(q/INSERT INTO hotter_than_previous_b VALUES(/ . $day->epoch . qq/, $temperature)/);
    }
    my $statement = $dbh->prepare(q/SELECT day FROM hotter_than_previous_a A INNER JOIN  
                                    hotter_than_previous_b B WHERE (A.day - B.day = 86400)                            
                                    AND A.temperature > B.temperature/);
    $statement->execute();
    while(my $row = $statement->fetchrow_hashref()){
        push @hotter, $row->{day};
    }
    @hotter = map {Time::Piece->strptime($_, q/%s/)->strftime(q/%Y-%m-%d/)} sort @hotter;
    unlink(q/hotter_than_previous_a/);
    unlink(q/hotter_than_previous_b/);
    return @hotter;
}

MAIN:{
    my $data = do{
        local $/;
        <DATA>; 
    };
    my @hotter = hotter_than_previous([split(/\n/, $data)]);
    say join(qq/\n/, @hotter);
}

__DATA__
2022-08-01, 20
2022-08-09, 10
2022-08-03, 19
2022-08-06, 24
2022-08-05, 22
2022-08-10, 28
2022-08-07, 20
2022-08-04, 18
2022-08-08, 21
2022-08-02, 25

Sample Run


$ perl perl/ch-2.pl
2022-08-02
2022-08-05
2022-08-06
2022-08-08
2022-08-10

Notes

To be clear up front, this is an intentionally over engineered solution! I have been intrigued by the idea of DBD::CSV since I first heard of it but never had a reason to use it. So I invented a reason!

DBD::CSV provides a SQL interface to CSV data. That is, it allows you to write SQL queries against CSV data as if they were a more ordinary relational database. Very cool! Instead of solving this problem in Perl I am actually implementing the solution in SQL. Perl is providing the implementation of the SQL Engine and the quasi-database for the CSV data.

DBD::CSV is quite powerful but is not completely on par feature wise with what you'd get if you were using an ordinary database. Not all SQL data types are supported, for example. Work arounds can be constructed to do everything that we want and these sorts of trade offs are to be expected. To store the dates we use Time::Piece to compute UNIX epoch times which are stored as INTEGERs. Also, DBD::CSV expects data from files and so we can't use the data directly in memory, it has to be written to a file first. Actually, we find out that we need to create two tables! Each hold exact copies of the same data.

The creation of two tables is due to a quirk of the underlying SQL Engine SQL::Statement. SQL::Statement will throw an error when doing a join on the same table. The way one would do this ordinarily is something like SELECT day FROM hotter_than_previous A, hotter_than_previous B .... That join allows SQL to iterate over all pairs of dates but this throws an error when done with SQL::Statement. To work around this we instead we create two tables which works.

References

Challenge 181

Dancer2: Return JSON

Perl Maven

Published by Gabor Szabo on Friday 09 September 2022 10:40

Part of the Dancer2 video course available both to Pro subscribers and attendees of the Perl Dancer course on Leanpub.

#580 - Perl Mentor

Perl Weekly

Published on Monday 05 September 2022 10:00

Hi there,

Good luck to all parents with school going kids in England, as today is the day one after a long summer vacation. I am one of them, fortunately or unfortunately. Be strong and you will get through this phase of life too.

Parents are the best mentor for their kids, in my humble opinion. During my early days, I didn't know the importance of mentor. Having met some great mentor in real life in the recent times, I can say it is great service. In 2018, I gave a short talk on The power of mentoring, at London Perl Workshop. A work colleague who does mentoring as part of his role, is by far the best mentor, I have met so far. I learn something new every day from him by just joining him on daily standup. Although my contribution to the standup is nothing but it feels nice to see young blood with so much energy. I wish I had mentor like him when I started.

I remember there was an initiative started on private Facebook group to encourage and help newbie. Unfortunately nothing happened although we had loads of mentor in the group.

Is it easy to be a mentor?

You would think so but I can tell you it is not. You have to have patience first thing first. I have seen how difficult it is to be a mentor. I would like to share a sweet moment with you. A month ago, a young blood interested to learn Perl reached out to me on Facebook. At times, I wonder how did he find out about me. His question was, how do I execute Hello World script, he has already created. He was using VSCode editor. I am not a big fan of VSCode editor but in the current role, I got the opportunity to use it. Having said, I still use vim for everything else. Back to the story, we started talking on Facebook messenger. I find it hard to convey message on messenger. So I requested him to join on Team video call. It took 2 minutes call to resolve the issue. While there, I showed him few other things beyond, hello world. I am sure, he would carry on exploring the language further.

Is it mostly about Perl?

In my personal experience, no. I was once contacted by a member of Team PWC with regard to the git related issues as he couldn't submit his contribution to the weekly challenge. So there again, we jumped on Team video call and in no time, he was good to go. Just to be explicit here, he was not a newbie but an experienced techie with way more than experience than me. It feels great to help. It is not one-way traffic as when I get stuck, I know who to contact. Luckily I get instant help too, so far. Few months ago, when I used to do YouTube video, I had trouble with OBS Studio. I asked for help on Twitter. You wouldn't believe, I had more help than I expected from Olaf Alders, Lance Wicks and Julien Fiegehenn. I now have working environment back, although I am not doing live video any more because of lack of time.

For those, need help can reach out to me on Twitter and Facebook. I must make this clear, I will not do your course work. I am available for anyone anytime as I literally spend 12-14 hours in front of machine every day.

Have a great week and enjoy rest of the newsletter.

First Uniquely Trimmed Index

RabbitFarm Perl

Published on Sunday 04 September 2022 11:57

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

Part 1

You are given a string, $s. Write a script to find out the first unique character in the given string and print its index (0-based).

Solution


use v5.36;
use strict;
use warnings;

sub index_first_unique{
    my($s) = @_;
    my @s = split(//, $s);
    map {my $i = $_; my $c = $s[$i]; return $_ if 1 == grep {$c eq $_ } @s } 0 .. @s - 1;
}

MAIN:{
    say index_first_unique(q/Perl Weekly Challenge/);
    say index_first_unique(q/Long Live Perl/);
}

Sample Run


$ perl perl/ch-1.pl
0
1

Notes

I use the small trick of return-ing early out of a map. Since we only want the first unique index there is no need to consider other characters in the string and we can do this short circuiting to bail early.

Part 2

You are given list of numbers, @n and an integer $i. Write a script to trim the given list when an element is less than or equal to the given integer.

Solution


use v5.36;
use strict;
use warnings;

sub trimmer{
    my($i) = @_;
    return sub{
        my($x) = @_;
        return $x if $x > $i;
    }
}

sub trim_list_r{
    my($n, $trimmer, $trimmed) = @_;
    $trimmed = [] unless $trimmed;
    return @$trimmed if @$n == 0;
    my $x = pop @$n;
    $x = $trimmer->($x);
    unshift @$trimmed, $x if $x;
    trim_list_r($n, $trimmer, $trimmed);
}

sub trim_list{
    my($n, $i) = @_;
    my $trimmer = trimmer($i);
    return trim_list_r($n, $trimmer);
}

MAIN:{
    my(@n, $i);
    $i = 3;
    @n = (1, 4, 2, 3, 5);
    say join(", ", trim_list(\@n, $i));
    $i = 4;
    @n = (9, 0, 6, 2, 3, 8, 5);
    say join(", ", trim_list(\@n, $i));
}

Sample Run


$ perl perl/ch-2.pl
4, 5
9, 6, 8, 5

Notes

After using map and grep in the first part this week's challenge I decided to try out something else for this problem. grep would certainly be a perfect fit for this! Instead, though, I do the following:

  • Create an anonymous subroutine closure around $i to perform the comparison. The subroutine is referenced in the variable $trimmer.
  • This subroutine reference is then passed to a recursive function along with the list.
  • The recursive function accumulates numbers meeting the criteria in an array reference $trimmed. unshift is used to maintain the original ordering. I could have also, for example, processed the list of numbers in reverse and using push. I haven't used unshift in a long time so this seemed more fun.
  • $trimmed is returned to when the list of numbers to be reviewed is exhausted.

This works quite well, especially for something so intentionally over engineered. If you end up trying this yourself be careful with the size of the list used with the recursion. For processing long lists in this way you'll either need to set no warnings 'recusion or, preferably, goto __SUB__ in order to take advantage of Perl style tail recursion.

References

Challenge 180

Distribution auf Dist::Zilla umstellen

Perl-Academy.de

Published on Friday 02 September 2022 10:00

In diesem Artikel zeige ich dir, wie du eine bestehende Distribution mit möglichst wenig Aufwand auf Dist::Zilla umstellen kannst.

List of new CPAN distributions – Aug 2022

Perlancar

Published by perlancar on Thursday 01 September 2022 03:01

dist author first_version latest_version abstract
API-Octopart EWHEELER 1.001 1.001 Simple inteface for querying part status across vendors at octopart.com.
Acme-CPANModules-WordListBundle-Proverbs PERLANCAR 0.001 0.001 All proverbs WordList modules (in all languages)
Algorithm-Graphs-Reachable-Tiny AAHAZRED 0.01 0.03 Compute rechable nodes in a graph.
Alien-Build-Plugin-Fetch-HostAllowList PLICEASE 0.01 0.01 Require that Alien::Build based aliens only fetch from an allow list of hosts
Alien-Build-Plugin-Fetch-HostBlockList PLICEASE 0.01 0.01 Reject any Alien::Build fetch requests going to hosts in the block list
Alien-Libdogecoin CHROMATIC v0.1.1 v0.1.1.1 Discover or download and install libdogecoin
App-FontUtils PERLANCAR 0.001 0.001 Command-line utilities related fonts and font files
App-Games-Keno TYUPYRCML 1.222380 1.222380 Plays Keno
App-InvestSim MATHIAS v0.8.0 v1.0.1 Simulateur d'investissement locatif
App-Keno TYUPYRCML 1.222380 1.222380 Plays Keno
App-Perl-Module-Examples SKIM 0.01 0.01 Tool for creating examples from Perl module POD documentation.
App-Schema-Deploy SKIM 0.01 0.02 Base class and script for Schema deploy.
Bencher-Scenarios-Data-Walk-More PERLANCAR 0.001 0.001 Scenarios to benchmark Data::Walk::More
Bundle-DadaMail-IncludedInDistribution JJSIMONI v0.0.1 v0.0.2 CPAN Bundle of modules used in Dada Mail that are included within the distribution.
Cache-CodeBlock LNATION 0.01 0.02 caching via a code block
Check-Fork SKIM 0.01 0.03 Check fork functionality.
Check-Socket SKIM 0.01 0.02 Check socket functionality.
Chemistry-File-CML MERKYS 0.10 0.11 CML reader
ControlBreak PUCKERING 1.00 v0.22.243 Compare values during iteration to detect changes
CryptoTron-AddrTools ZTENRETEP 0.01 0.05 Perl extension for blah blah blah
Cucumber-Test-Release-Automation CUKEBOT 0.0.0 v0.0.39 Dummy project for testing release automation
Data-Sah-FilterBundle-Phone PERLANCAR 0.001 0.001 Sah filters related to phone numbers
Date-Holidays-BQ WATERKIP 0.001 0.001 Bonaire's official holidays
Date-Holidays-US MRDVT 0.01 0.02 Date::Holidays Adapter for US Federal holidays
Devel-MAT-Tool-Future PEVANS 0.01 0.01 analyse Future logic
English-Name LEONT 0.001 0.002 ${^ENGLISH_NAME} for magic variables
Feature-Compat-Class PEVANS 0.01 0.01 make class syntax available
Finance-Libdogecoin CHROMATIC 1.20220814.2215 1.20220815.1712 Use the libdogecoin shared library from Perl!
Future-XS PEVANS 0.01 0.03 experimental XS implementation of Future
Glitch LNATION 0.01 0.06 The great new Glitch!
HTTP-Curl KNI 1.03 1.04 HTTP interface for Net::Curl (clone HTTP::Any::Curl)
HV-Monitor VVELOX v0.0.1 v0.0.2 A generalized module for gathering stats for a hypervisor.
Hydrogen TOBYINK 0.001 0.015 utilities for the simplest elements of Perl
Iss-Ah-Predictor CHRISTOPH v0.1.0 v0.1.0 ISS AH Predictor
Math-Permutation CYFUNG 0.01 0.01 pure Perl implementation of functions related to the permutations
Mojolicious-Plugin-Access CARELINE 0.001 0.002 Mojolicious::Plugin::Access Control remote ip access your App
Mooish-AttributeBuilder BRTASTIC 0.001 0.002 build Mooish attribute definitions with less boilerplate
Net-HTTP2 FELIPE 0.01_01 0.01_01 HTTP/2 in Perl, simplified.
Net-MBE ARTHAS 0.2.0 0.2.2 Perl library to access Mailboxes Etc (MBE) online webservices
Net-Wait JJATRIA 0.001 0.001 Wait on startup until the specified ports are listening
Optimization-NSGAII DRUBINO 0.01 0.01 non dominant sorting genetic algorithm for multi-objective optimization
Perl-Critic-Policy-Modules-RequireExplicitPackage-ObjectPad DERIV 0.001 0.001 Always make the package/Object::Pad class explicit.
Perl-Critic-Policy-Variables-ProhibitNumericNamesWithLeadingZero WYANT 0.001 0.002 Don't use numeric variable names with leading zeroes.
PickLE NATHANPC v0.1.0 v0.1.0 An electronic component pick list application and file parser library.
Plack-App-GitHubPages-Faux PLICEASE 0.02 0.02 PSGI app to test your GitHub Pages site
Sah-Schemas-Re PERLANCAR 0.001 0.001 Various regular-expression schemas
ScalarTypes-NumericTypes ZTENRETEP 0.01 0.11 Perl extension for identifyling special types of numbers
Schema-Abstract SKIM 0.01 0.03 Abstract class for Schema modules.
TableDataBundle-Locale-JP-City PERLANCAR 0.001 0.001 Collection of TableData:: modules that contain list of cities in Japan
Term-ANSIColor-Concise UTASHIRO 2.00_03 2.01 Produce ANSI terminal sequence by concise notation
Terminal-Control ZTENRETEP 0.01 0.06 Perl extension for terminal control
Test-Pod-CoverageChange BINARY 0.002 0.003 Test Perl files for POD coverage and syntax changes
Test-Sah-Filter PERLANCAR 0.001 0.001 Test Data::Sah::Filter::* modules in distribution
Voo ECARROLL 42.42 42.43 Run functions at compile time, not runtime!
WebService-eBay TYUPYRCML 0.001 0.005 Interface with the eBay API
XML-LibXML-xmlsec ESTRELOW 0.01 0.03 XML signing/encription using xmlsec library
XML-LibXMLSec DAKKAR 0.010 0.010 bindings to some of xmlsec1
XML-XPath-Helper-String AAHAZRED 0.01 1.01 Helper functions for xpath expression
app-paperback MONACCI 0 1.11 imposition of PDF pages for signature printing and bounding
perl-Test-Pod-CoverageChange DERIV 0.002 0.002 Test Perl files for POD coverage and syntax changes
perl-app-paperback MONACCI 0.33 0.33 imposition of PDF pages for signature printing and bounding

Stats

Number of new CPAN distributions this period: 61

Number of authors releasing new CPAN distributions this period: 38

Authors by number of new CPAN distributions this period:

No Author Distributions
1 PERLANCAR 7
2 SKIM 5
3 TYUPYRCML 3
4 PEVANS 3
5 ZTENRETEP 3
6 PLICEASE 3
7 DERIV 2
8 LNATION 2
9 AAHAZRED 2
10 MONACCI 2
11 CHROMATIC 2
12 MERKYS 1
13 TOBYINK 1
14 ECARROLL 1
15 JJSIMONI 1
16 MATHIAS 1
17 UTASHIRO 1
18 JJATRIA 1
19 NATHANPC 1
20 KNI 1
21 WYANT 1
22 EWHEELER 1
23 ESTRELOW 1
24 CHRISTOPH 1
25 FELIPE 1
26 DRUBINO 1
27 CYFUNG 1
28 WATERKIP 1
29 PUCKERING 1
30 MRDVT 1
31 LEONT 1
32 CARELINE 1
33 CUKEBOT 1
34 DAKKAR 1
35 BINARY 1
36 ARTHAS 1
37 VVELOX 1
38 BRTASTIC 1

#579 - Looking for that motivation

Perl Weekly

Published on Monday 29 August 2022 10:00

Hi there!

Last time I mentioned the numbers I collect with the number of visitors to CPAN and I was wondering about the increased activity starting in August 2011. I got a few comments in email and some on Reddit.

Probably the best explanation is what I received from Neil Bowers:

Have a look at the CPAN report I did in February. If you look at the new user signups, you'll see a jump in 2012, and also looking at that chart you'll see that 2012, 2013, and 2014 seem to buck a trend.

In 2012 Intermediate Perl was released, which told the reader to sign up for a PAUSE account and release a test module. If I remember right, brian d foy ran a tutorial at YAPC::NA the previous year, where he also got people to sign up (not sure if the tutorial was 2011 or 2012). We had the first CPAN Day in 2014, which also resulted in a big bump in CPAN releases. That may have helped 2014 stay up above the trend.

The question now, what could be a new motivation to increase activity and if there could be one that is sustainable?

Enjoy your week!