AI 资讯
Perl PAGI Middleware
Middleware in PAGI A port of the sample app from What Is Middleware? — which builds the same three-layer stack in Plack/PSGI (Perl) and Starlette/ASGI (Python) — to PAGI , an async, ASGI-style application interface for Perl. The app is deliberately tiny but exercises the three things middleware exists to do: Logger — wrap the request, time it, log method/path in and status/duration out. Authenticator — inspect a header, inject context for downstream layers on success, or short-circuit with a 401 on failure. ProfileRouter — answer one specific route from inside the stack, reading the context the Authenticator injected. All code below was run under perl-5.40.0 with PAGI::Test::Client ; the log lines and responses shown in Running it are the actual captured output, not hand-written. The PAGI middleware contract A PAGI application is, in the spec's words, "a single coderef returning a Future": an async sub over the ($scope, $receive, $send) triple — the same shape as ASGI. $scope is the per-connection metadata hash ( type , method , path , headers , …), $receive pulls inbound events, $send pushes outbound ones ( http.response.start , then http.response.body ), and the Future it returns resolving is what tells the server the response is complete. Middleware is just as plain: a subroutine that takes an application and returns a new application, wrapping the inner one. That is the whole spec-level contract — app in, app out: sub middleware { my ( $app ) = @_ ; return async sub ($scope, $receive, $send) { # ... before ... await $app -> ( $scope , $receive , $send ); # call the inner app # ... after ... }; } A middleware propagates the inner app's Future — its completion and any exception flow straight through — and never reads its return value, which the spec defines as inert; to observe or rewrite the response it wraps $send instead, and to add per-request context it clones $scope (top-level edits stay visible downward only). PAGI::Middleware , from PAGI-Tools rather than
AI 资讯
Perl 🐪 Weekly #777 - Check your CPAN profile!
Originally published at Perl Weekly 777 Hi there! In the recent weeks I looked at a lot of MetaCPAN profiles (aka. author pages) such as that of MANWAR . If I could also find their LinkedIn profile I invited them to connect via LinkedIn . (If I have not sent you an invitation yet, then I guess I missed your profile. I'd be glad to get a connect request via LinkedIn.) I noticed that a large percentage of the people still have their @cpan.org email address listed. Despite the fact that cpan.org email forwarding has been shut down 6 weeks ago. That means people will get annoyed if hey try to contact you using that address. You could replace that address or hide it and offer other ways for people to contact you. Either of them is better than having a bad address. In addition, I noticed that some of the links people have there are not working. (e.g. incorrect link to their LinkedIn profile, or to their home page etc.) In order to fix these you probably first need to check and update your PAUSE account . After logging in look for the Edit Account Info menu option. There you can list your email address and you can even decide if you'd like to have a visible address or not. Then you could take a look at your MetaCPAN profile. For this visit MetaCPAN . Login in the top-right corner. If you don't remember whether you used GitHub or Google, don't worry. Inside you can connect them in the Identities menu point. Then go to the Profile menu point and update the fields there. Finally, if you have updated your profile after reading this, I'd be glad if you sent me an email so I'll know this messaged had some positive impact. Oh, and if you don't have a CPAN account and you have not uploaded anything yet, then what are you waiting for? Enjoy your week! -- Your editor: Gabor Szabo. Articles Time::Str - Time Zones and Leap Seconds Time::Str parses and formats date/time strings across 20+ standard formats, with an optional C/XS backend and nanosecond precision. The previous post, Intro
AI 资讯
Weekly Challenge: Existence
Weekly Challenge 377 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. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding. Challenge , My solutions Task 1: Reverse Existence Task You are given a string. Write a script to find whether any substring of length 2 is also present in the reverse of the given string. My solution This is relatively straight forward. I create a variable reversed_string which is the string reversed. I then have a loop called start_pos that goes from 0 to 2 less than the length of the string. At each position, I check if the two letters at that position are in the original string. def reverse_existence ( input_string : str ) -> bool : reversed_string = input_string [:: - 1 ] for start_pos in range ( len ( input_string ) - 1 ): if reversed_string [ start_pos : start_pos + 2 ] in input_string : return True return False The Perl solution follows the same logic. sub main ($input_string) { my $reversed_string = reverse ( $input_string ); foreach my $start_pos ( 0 .. length ( $input_string ) - 2 ) { if ( index ( $input_string , substr ( $reversed_string , $start_pos , 2 ) ) != - 1 ) { say " true "; return ; } } say " false "; } Examples $ ./ch-1.py abcba true $ ./ch-1.py racecar true $ ./ch-1.py abcd false $ ./ch-1.py banana true $ ./ch-1.py hello true Task 2: Prefix Suffix Task You are given an array of strings. Write a script to find if the two strings ( str1 , str2 ) in the given array such that str1 is prefix and suffix of str2. Return the total count of such pairs. My solution In Python, this is a one line solution. I use the combinations function from the itertools module to produce all combinations of pairs of str1 and str2 . For each pair, I use the startwith and endswith function on the strings
AI 资讯
Building Video Heatmap Analytics with HyperLogLog in Postgres
The problem: counting unique viewers per second is a row explosion A viewer scrubs to 4:12 of a 9-minute trending clip, watches for 40 seconds, jumps back to the intro, then bounces. Multiply that by the few hundred thousand sessions a day that hit a mid-size aggregator and you get the question every product person eventually asks: which parts of this video do people actually watch, and how many distinct people watched each part? The naive answer is a watch_events table: one row per (user, video, second) . It works until it doesn't. A 9-minute video is 540 seconds. One viewer who watches the whole thing generates 540 rows. A million viewers across our catalog generate hundreds of millions of rows per day , and the only query anyone runs against them is COUNT(DISTINCT user_id) GROUP BY second . That COUNT(DISTINCT) is a sort-or-hash over the entire partition every single time someone opens the analytics tab. At TopVideoHub we aggregate trending video across Asia-Pacific, so a single popular clip can spike from zero to half a million sessions in an afternoon when it lands in the JP and KR feeds simultaneously. We did not want a fact table that grew by hundreds of millions of rows a day to answer a question whose answer is approximately fine. "Roughly 41,000 unique viewers saw the hook at 0:08" is just as actionable as "41,287". That tolerance for approximation is exactly what HyperLogLog is built for, and Postgres has a battle-tested extension for it. This post is the design we landed on: fixed-size HLL sketches, one per (video, time_bucket) , that you can merge, slice, and union across regions in milliseconds. The main app is PHP 8.4 on LiteSpeed behind Cloudflare, with our search layer on SQLite FTS5; the analytics store is a separate Postgres instance, and HLL is what made that store affordable. Why HyperLogLog instead of COUNT(DISTINCT) HyperLogLog estimates the cardinality of a set using a fixed amount of memory regardless of how many elements you throw at it. Th
AI 资讯
Perl 🐪 Weekly #776 - Learning Perl
Originally published at Perl Weekly 776 Hi there, Recently, I came across an article, The Day I Decided Never to Learn Python by Randal L. Schwartz . Well, Randal doesn't need an introduction. He took us back to 2001 , the same era when I first started learning Perl in 1999. He was a major guiding force during my early programming days. Last week, I joined a live session by Gabor focussed on FalkorDB . It was fun watching him code and talk while I sat back as a silent spectator. You can learn a lot just by watching how he approaches coding. It reminded me of many years ago when I did pair programming with him and submitted a pull request to the Dancer2 project. Those were the golden days, when I had so much energy and time. That being said, I am still actively learning Perl and discovering how to do new things with it. These concepts may not be new to everyone, but they are new to me. For example, I recently played with GraphQL for the first time, and I've also been experimenting with RAG and JSON-RPC . I have shared my recent experiments down below. The process of learning never stops. A few days ago, I noticed an update for HTTP::Message v7.02 . Since it was released by Olaf Alders , I was curious to see what had changed. It turned to be something, I hadn't realised for all these years. While I am well-acquainted with HTTP methods like GET, POST, and PUT, I didn't know "0" could actually be a valid HTTP method name if you wanted it to be. This release added support for exactly that, thanks to contributor, Karen Etheridge . Amidst all of this, I am still trying to find time for my upcoming book on DBIx::Class . I recently shared a blog post demonstrating the power of DBIC components, and I am trying my best not to lose focus. You might find that this edition is full of my own personal posts, as there was unfortunately very little community news to report this week. Regardless, I hope you enjoy the rest of the newsletter. -- Your editor: Mohammad Sajid Anwar. Announ
AI 资讯
Perl 🐪 Weekly #775 - Events and using AI to write Perl
Originally published at Perl Weekly 775 Hi there! I try to keep track of the Perl-related events. You can find them listed at the bottom of each edition of the newsletter and on the events page on the Perl Weekly web site. There you can also find a link to embed the calendar in your calendar program. There are a number of events scheduled for this month. Most of them online, so if your time-zone permits, you can join those events. The big in-person event is at the end of the month The Perl and Raku Conference in Greenville, South Carolina, USA. In the last couple of weeks I have been using various AI tools extensively. It still needs some hand-holding, but it already writes code that seems to be way better than the average code I've seen. So I wonder, would it be possible to ask one of the AI tools to convert Python libraries to Perl? You know, we have been complaining for many years that companies provide implementation for their SDK/API/client in several language, but not in Perl. We also saw that CPAN could not keep up with the growth of PyPI, npm and the other 3rd party library registries. So maybe some of you would like to explore the idea of converting some of these libraries to Perl using AI. Finally a personal note, I am planning a trip to Korea and Japan in September-October. If you live there and would have any travel recommendations, I'd love to get that. Enjoy your week! -- Your editor: Gabor Szabo. Articles Introducing ZuzuScript Toby Inkster created a programming language which blends a fairly JavaScript-like syntax with fairly Perl-like semantics, and a few other features that he hasn't really seen in many programming languages. ANNOUNCE: Perl.Wiki V 1.47, JSTree copy V 1.21 Teaching AI About the British Monarchy with MCP The site already exposes information through a traditional web interface and a JSON API. But those interfaces were designed for humans and developers respectively. MCP gives AI systems a much cleaner integration point. ANNOUNCE: Perl