Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Cool Uses for Perl

( #1044=superdoc: print w/replies, xml ) Need Help??

This section is the place to post your general code offerings -- everything from one-liners to full-blown frameworks and apps.

Type::Tiny v2 is Coming
No replies — Read more | Post response
by tobyink
on Sep 16, 2022 at 11:19

    Eagle-eyed watchers of CPAN may have noticed that I've recently been releasing Type::Tiny development releases with version numbers 1.999_XYZ.

    Type::Tiny v2 is intended to be compatible with Type::Tiny v1. If you've used Type::Tiny v1, you shouldn't need to change any code, but Type::Tiny v2 has a few new features which may make your code simpler, more maintainable, and more readable if you adopt them.

    Type::Params v2 API

    Type::Params can be used to provide typed subroutine signatures:

    use feature qw( state ); use Type::Params qw( compile ); use Types::Standard qw( Num ); sub add_numbers { state $signature = compile( Num, Num ); my ( $x, $y ) = $signature->( @_ ); return $x + $y; }

    However, things like named paramaters, catering for $self in methods, etc felt like afterthoughts. Here is how you'd write the same signature in version 1 as a method call using named parameters:

    use feature qw( state ); use Type::Params qw( compile_named_oo ); use Types::Standard qw( Num ); sub add_numbers { state $signature = compile_named_oo( { head => [ Any ] }, 'x' => Num, 'y' => Num, ); my ( $self, $arg ) = $signature->( @_ ); return $arg->x + $arg->y; }

    While the old API is still supported, Type::Params v2 has two new functions, signature and signature_for, which I feel provide a more powerful and more consistent interface.

    signature works much the same as compile, but takes a top-level hash of options, allowing it to cater for both positional and named parameters.

    Here is an example for positional parameters:

    use feature qw( state ); use Type::Params qw( signature ); use Types::Standard qw( Num ); sub add_numbers { state $signature = signature( method => 0, positional => [ Num, Num ], ); my ( $x, $y ) = $signature->( @_ ); return $x + $y; }

    Here is an example for named parameters:

    use feature qw( state ); use Type::Params qw( signature ); use Types::Standard qw( Num ); sub add_numbers { state $signature = signature( method => 1, named => [ 'x' => Num, 'y' => Num ], ); my ( $self, $arg ) = $signature->( @_ ); return $arg->x + $arg->y; }

    And signature_for allows you to turn that definition inside-out.

    use experimental qw( signatures ); use Type::Params qw( signature_for ); use Types::Standard qw( Num ); signature_for add_numbers => ( method => 1, named => [ 'x' => Num, 'y' => Num ], ); sub add_numbers ( $self, $arg ) { return $arg->x + $arg->y; }

    Handy import shortcuts

    A handy way to define an Enum type in Type::Tiny 2 is:

    use Type::Tiny::Enum Size => [ qw( S M L XL ) ];

    You can use this in a class like:

    package Local::TShirt { use Moose; use Types::Common -types; use Type::Tiny::Enum Size => [ qw( S M L XL ) ]; use namespace::autoclean; has size => ( is => 'ro', isa => Size, required => 1, ); sub price { my $self = shift; my $size = $self->size; if ( $size eq SIZE_XL ) { return 10.99; } elsif ( $size eq SIZE_L ) { return 9.99; } else { return 8.99; } } }

    Yes, Enum type constraints now provide constants like SIZE_XL above.

    Type::Tiny::Class provides a similar shortcut:

    sub post_data ( $url, $data, $ua=undef ) { use Type::Tiny::Class -lexical, 'HTTP::Tiny'; $ua = HTTPTiny->new unless is_HTTPTiny $ua; $ua->post( $url, $data ); }

    Type::Tiny::Role and Type::Tiny::Duck also provide shortcuts.


    Having checked out a lot of modules which use Type::Tiny, I've noticed that the most common modules people import from are Types::Standard, Type::Params, Types::Common::Numeric, and Types::Common::String.

    Types::Common is a new module that combines all of the above. For quick scripts and one-liners, something like this may save a bit of typing:

    use Types::Common -all;

    Though like always, you can list imports explicitly:

    use Types::Common qw( signature_for Num NonEmptyStr ); </pre> <p>If you have a bleeding-edge Perl installed, you can import function +s lexically:</p> <c> use Types::Common -lexical, -all;

    A type divided against itself shall stand

    You can now divide a type constraint by another:

    has lucky_numbers => ( is => 'ro', isa => ArrayRef[ Num / Any ], );

    What does this mean?

    Under normal circumstances, Num/Any evaluates to just Any. Num is basically just documentation, so you're documenting that lucky_numbers is intended to be an arrayref of numbers, but as a speed boost, the attribute will just check that it's an arrayref of anything.

    When the EXTENDED_TESTING environment variable is switched on though, Num/Any will evaluate to Num, so stricter type checks will kick in.

    Type defaults

    Instead of this:

    has output_list => ( is => 'ro', isa => ArrayRef, default => sub { [] }, );

    You can now write this:

    has output_list => ( is => 'ro', isa => ArrayRef, default => ArrayRef->type_default, );

    This is more typing, so why do this? Well, for ArrayRef it might be more typing, but in this case:

    has colour_scheme => ( is => 'ro', isa => ColourScheme, default => sub { my %colours = ( foreground => 'black', background => 'white', links => 'blue', highlight => 'red', ); return \%colours; }, );

    It might be neater to include the default in the definition of your ColourScheme type.

    The new DelimitedStr type

    Types::Common::String now has a DelimitedStr type.

    This allows DelimitedStr[ "|", Int ] to accept strings like "12|34|-99|0|1".


    There have been numerous internal refactorings in Type::Tiny v2, so if you're using Type::Tiny and its related modules in more unorthodox ways, it may be worth explicitly testing your code still runs on the new version.

    However, I have taken care to avoid breaking any documented APIs. The vast majority of the Type:Tiny v1 test suite still passes with Type::Tiny v2, with test cases that inspect the exact text of error messages being the only real change.

'rgb_palette' - Term::ANSIColor Helper
2 direct replies — Read more / Contribute
by kcott
on Aug 15, 2022 at 03:37

    G'day All,

    I've been playing around with Term::ANSIColor recently. I found the named colours to be very limited. The rgbRGB format provides additional colours but the codes are not particularly intuitive. Then I found rNNNgNNNbNNN; at first, I thought I'd need a different terminal but it turns out that it works just fine on my xterm.

    I'm quite familiar with the hex notation #rrggbb, but less so with the decimal equivalents; so I wrote myself a helper program: rgb_palette. I thought I'd share; but there are a few things you'd probably want to know up-front.

    • Obviously, you'll need a true color (aka direct-color) terminal.
    • Change the shebang line if it doesn't fit your setup.
    • Install IO::Prompter.
    • The code, as is, has "use v5.36;". You can downgrade this but, if you do, deal with the subroutine signatures (either turn off experimental warnings or rewrite the two short subroutines, e.g. "sub fg ($r, $g, $b) { ..." --> "sub fg { my ($r, $g, $b) = @_; ..."). Also, add in whatever pragmata you're no longer getting for free.
    • I use a black background. You may need to fiddle with some of the text colours if you use something else.
    • I initially had the hex values on each of the coloured swatches in either black or white. I found this distracting; change the commented code in fg() if you want to put it back that way. As it stands, the foreground and background colours are the same making the text invisible but the swatch colour more prominent. I just double-click on a swatch; middle-click to paste; then "Enter" to get the rNNNgNNNbNNN conversion.
    • I've aimed to get a lot of colours without needing a giant screen. You'll need 100 columns and scrolling will almost certainly be necessary. You can also type in your own hex codes if you want: the output shows a swatch of the input value as well as the rNNNgNNNbNNN code.

    Alright, that's enough blathering, here's the code:

    #!/usr/bin/env perl use v5.36; use IO::Prompter [ -style => 'bold blue', -echostyle => 'bold magenta', ]; use Term::ANSIColor 5.00; my @nums_under_255 = qw{0 26 51 77 102 127 153 179 204 230 243}; say ''; for my $r (@nums_under_255, 255) { for my $g (@nums_under_255, 255) { print ' '; for my $b (@nums_under_255) { print colored(text("r${r}g${g}b${b}"), join(' on_', fg($r, + $g, $b), "r${r}g${g}b${b}")); } say colored(text("r${r}g${g}b255"), join(' on_', fg($r, $g, 25 +5), "r${r}g${g}b255")); } } say ''; my $rgb; while (1) { $rgb = prompt 'Convert hex to decimal rgb (or just hit "Enter" to +quit): ', -return => ''; # Fix for MSWin -- see +?id=118255 $rgb =~ s/\R\z//; unless (length $rgb) { say ''; last; } if ($rgb =~ /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/) +{ my $ansi_rgb = sprintf 'r%dg%db%d', map hex, $1, $2, $3; print colored(' --> [', 'bold white'); print colored(' ' x 8, "$ansi_rgb on_$ansi_rgb"); print colored('] --> ', 'bold white'); say colored($ansi_rgb, 'bold cyan'); } else { say colored("\nERROR: '", 'r255g0b0 on_r51g51b51'), colored($rgb, 'r255g255b0 on_r51g51b51'), colored( "' is invalid. Six hexadecimal characters are expected +; such as in the table above.", 'r255g0b0 on_r51g51b51' ); } } sub fg ($r, $g, $b) { #return $r + 2 * $g + $b > 204 ? 'black' : 'white'; return "r${r}g${g}b${b}"; } sub text ($str) { return sprintf ' %02x%02x%02x ', $str =~ /^r(\d+)g(\d+)b(\d+)$/; }


    Updates: Some people encountered problems, so I've made changes.

    • Term::ANSIColor introduced support for 24-bit colour in v5.00 (see Changes). I wasn't aware of this. I've changed "use Term::ANSIColor;" to "use Term::ANSIColor 5.00;". Thanks ++pryrt for reporting this.
    • For MSWin users, there's a bug in IO::Prompter. Again, thanks ++pryrt for reporting this. As a workaround, I've added:
      # Fix for MSWin -- see +?id=118255 $rgb =~ s/\R\z//;
    • Also for MSWin users, there's been some discussion, in a number of responses, about whether the module Win32::Console::ANSI, or the registry setting VirtualTerminalLevel, is required for this code to work. Not being in a position to test this, I can't comment further.

    — Ken

Challenge: sort weekdays in week-order (elegantly and efficiently)
10 direct replies — Read more / Contribute
by bliako
on Jul 21, 2022 at 10:08

    It just occured to me that I do not know how to sort weekdays in week-order except with this:

    my @weekdays = qw/Monday Saturday Thursday/; my %order = ( monday => 1, tuesday => 2, wednesday => 3, thursday => 4, friday => 5, saturday => 6, sunday => 7, ); print join ",", map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [$_, $order{lc $_}] } @weekdays;

    is there a way without using that %order?

    bw, bliako

Range check with unordered limits
4 direct replies — Read more / Contribute
by hexcoder
on Jul 10, 2022 at 14:00
    Suppose you want to check if an integer is inside a given range. That seems trivial, if the range minimum and maximum are known ahead.
    $inRange = $a <= $x && $x <= $b;

    But if you don't know which one is minimum and which one is maximum, the algorithm should be a bit more flexible. Here is where Perl's spaceship operator can help. I came up with:

    $inRange = (($a <=> $x) * ($b <=> $x)) < 1;
    where $a and $b are the unordered range limits and $x is the variable to be tested.

    Could this be optimized (reduced) further? I would be interested to know.

    Thanks, hexcoder

Bulk check for successful compilation
2 direct replies — Read more / Contribute
by davebaker
on Jul 02, 2022 at 17:16

    Just a note to say how much fun it was for me to try the Test::Compile::Internal module, which zips through every Perl module and script in my cgi-bin directory and its subdirectories, making sure each such file successfully compiles.

    This lets me feel more at ease about there not being any lurking problems that have arisen due to my having renamed or deleted some custom module, and that scripts or modules I'm still developing haven't "use"d a module and its specified subroutines (whether custom or in my Perl libraries) in a way that misspelled the module name or the subroutine name, or that tries to import a subroutine that doesn't actually exist in the "use"d module (such as a subroutine I meant to add to a "use"d custom module but never got around to adding).

    #!/opt/perl524 use strict; use warnings; use Test::Compile::Internal; my $test = Test::Compile::Internal->new(); $test->all_files_ok( '/www/cgi-bin' ); $test->done_testing();

    (Edited 7/7/2022 to add hypertext link to page of the Test::Compile::Internal module)

Mite: an OO compiler for Perl
No replies — Read more | Post response
by tobyink
on Jul 02, 2022 at 13:34

    This article has also been posted on here.

    Moose is great, but it does introduce a slight performance hit to your code. In the more than 15 years since it was first released, hardware improvements have made this less of a problem than it once was. Even so, if performance is a concern for your project, Moose might not be what you want. It also has a fairly big collection of non-core dependencies.

    Moo is a lighter weight version, minus with meta-object protocol, but supporting nearly all of Moose's other features. It loads faster, sometimes runs faster, and has fewer dependencies. (And most of the dependencies it does have are just modules which used to be part of Moo but were split out into separate distributions.)

    But what if you could have fast Moose-like object-oriented code without the dependencies?

    In 2013, Michael Schwern started work on Mite to do just that. It was abandoned in 2014, but I've taken it over and expanded the feature set to roughly equivalent to Moo.

    Mite is an object-oriented programming compiler for Perl. It allows you to write familiar Moose-like object-oriented code, then compile that into plain Perl with zero non-core dependencies. Your compiled code does not even have a dependency on Mite itself!

    How do I use Mite?

    Here's how you could start a project with Mite or port an existing Moose/Moo project.

       cd Your-Project/
       mite init 'Your::Project'
       mite compile

    After you've run those commands, Mite will create a module called Your::Project::Mite. This module is your project's own little gateway to Mite. This module is called the shim.

    Now let's write a test case:

       # t/unit/Your-Project-Widget.t
       use Test2::V0
          -target => 'Your::Project::Widget';
       can_ok( $CLASS, 'new' );
       my $object = $CLASS->new( name => 'Quux' );
       isa_ok( $object, $CLASS );
       subtest 'Method `name`' => sub {
          can_ok( $object, 'name' );
          is( $object->name, 'Quux', 'expected value' );
          my $e = dies {
             $object->name( 'XYZ' );
          isnt( $exception, undef, 'read-only attribute' );
       subtest 'Method `upper_case_name`' => sub {
          can_ok( $object, 'upper_case_name' );
          is( $object->upper_case_name, 'QUUX', 'expected value' );

    And a class to implement the functionality:

       # lib/Your/Project/
       package Your::Project::Widget;
       use Your::Project::Mite;
       has name => (
          is     => 'ro',
          isa    => 'Str',
       sub upper_case_name {
          my $self = shift;
          return uc( $self->name );

    Run mite compile again then run the test case. It should pass.

    How does Mite work?

    It's important to understand what Mite is doing behind the scenes.

    When you ran mite compile, Mite created a file called lib/Your/Project/ (Yes, a triple file extension!) This file contains your class's new method. It contains the code for the accessor.

    That file does not contain the code for upper_case_name which is still in the original lib/Your/Project/

    When Perl loads Your::Project::Widget, it will see this line and load the shim:

       use Your::Project::Mite;

    The shim just loads lib/Your/Project/, exports a has function that does (almost) nothing, and then gets out of the way. This gives Perl a working class.

    What features does Mite support?

    Most of what Moo supports is supported by Mite. In particular:

    extends @superclasses

    Mite classes within your project can inherit from other Mite classes within your project, but not from non-Mite classes, and not from Mite classes from a different project.

    with @roles

    As of version 0.002000, Mite also supports roles. If you want your package to be a role instead of a class, just do:

       package Your::Project::Nameable;
       use Your::Project::Mite -role;
       has name => (
          is => 'ro',
          isa => 'Str',

    As with extends, a limitation is that you can only use Mite roles from within your own project, not non-Mite roles, nor Mite roles from a different project.

    (A future development might add support for Role::Tiny roles though.)

    has $attrname => %spec

    Attributes are obviously one of the main features people look for in a Perl object-oriented programming framework and Mite supports nearly all of Moose's features for defining attributes.

    This includes is => 'ro', is => 'rw', is => 'bare', is => 'rwp' (like Moo), and is => 'lazy' (like Moo); required and init_arg for attribute initialization; reader, writer, accessor, predicate, clearer, and trigger; lazy, default, and builder; weak_ref; isa and coerce for type constraints, including support for any type constraints in Types::Standard, Types::Common::Numeric, and Types::Common::String; and delegation using handles. It also supports an option which Moose doesn't provide: alias for aliasing attributes.

    Mite builds in the functionality of MooseX::StrictConstructor, dying with an appropriate error message if you pass your class's constructor any parameters it wasn't expecting.


    Methods you can define to control the life cycle of objects.

    before $method => sub { ... }
    after $method => sub { ... }
    around $method => sub { ... }

    Mite classes and roles can define method modifiers.

    As long as your needs aren't super-sophisticated (introspection using the MOP, runtime application of roles, etc), Mite probably has the features you need for even medium to large projects.

    Mite itself uses Mite!

    Be honest, what are the drawbacks?

    This code still doesn't have a lot of testing "in the wild". Moose and Moo have proven track records.

    You need to remember to mite compile your code after making changes before running your test suite or packaging up a release. This can be annoyingly easy to forget to do. (Though Mite does also include extensions for ExtUtils::MakeMaker and Module::Build to help integrate that into your workflow.)

    The Mite compiler's scope of only looking at the files within your own project limits the ability to create roles which can be composed by third-parties, or classes which can easily be extended by third-parties. If you want that, Moose or Moo are a better option.

    Okay, I'm interested

    If you've read this and you're thinking about porting a Moose or Moo project to Mite, feel free to @-mention tobyink on Github in issue tickets, pull requests, etc if you need any help.

    If there are features which you think Mite is missing which you'd need to port your project to Mite, file bugs with the Mite issue tracker.

COMET DANCER - scafolding for Dancer2
No replies — Read more | Post response
by AlexP
on Jun 19, 2022 at 06:33

    After several months of development, I would like to present COMET DANCER - scaffolding for your Dancer2 apps.

    You could find all code, screenshots and description here -> github/comet-dancer.


    Dancer is minimalist, and if you are developing a small app or simple api it's very convenient to use. But if you try to create a bigger app you will encounter a lack of documentation and any examples.

    What is Comet Dancer

    You could think about it like a foundation for web-app. It provides you with a ready environment for application development. You just clone it and get a complete set of tools.

    How to start

    Visit the link above and go through the easy installation process.

    Do you need contributors?

    Yes. If you are interested in Perl and Dancer - you are welcome!

pl Perl One-Liner Magic Wand: looking for feedback
4 direct replies — Read more / Contribute
by Daniel Pfeiffer
on Jun 03, 2022 at 16:58

    One of my favourite Cool Uses for Perl have always been one-liners. But already decades ago I found them still too cumbersome. So, I rolled a wrapper, a better perl -E. When Corona went viral, I decided to publish it, after a major clean up. But I never advertised, beyond meta::cpan and Sourceforge.

    The base idea is a small script I can take to any server where I need to get stuff done. It's self-contained, as many data center hosts are firewalled off from the internet. It supports old Perls: With SuSE SLES 11 and 5.10 out of the way, it's now on 5.16, which comes with Red Hat RHEL 7.

    In hindsight, the added options are powerful, but the way I intertwined them into -n handling is ugly & limiting. Thus, I'm rewriting the wrapping code for pl 1.0. From that comes a small but rich template mechanism (interpolation or sprintf meh.) That's just one of many goodies it contains, like the mighty multi-file key-based diff. There are a bunch of examples, many original:

    May the veggie-burger menu guide you!

PerlPowerTools as single Windows executable
1 direct reply — Read more / Contribute
by kaldor
on May 26, 2022 at 16:25

    For a long time, I've been looking for a solution to bring Mac, Windows and Linux behaviour closer. My use case : I work in a corporate Windows environment (where you don't want to install unecessary software), but still would like a friendly CLI (I'm not great at it).

    I use UnxUtils, BusyBox-w32 and other utils to have a bearable experience on Windows, but they don't provide the same features/options as you'll find on macOS or Linux. Then I heard about the PerlPowerTools and thought they'd be perfect for having the same behaviour across these platforms. Even though I somehow find them hard to use due to namespace conflict with system utilities.

    So, I've updated (my fork of) the PerlPowerTools to behave like BusyBox and bundle them (with PAR::Packer) as a single Windows executable.

    Result : You can call the tools similarly on all three platforms.

    bin/cat bin/perlpowertools cat packed/perlpowertools.exe cat packed/cat.exe

    The additional benefit is that I can complement my Windows toolbox with my own (Perl) scripts. For example, add ack! to perlpowertools.exe just by copying the singl e-file version to PerlPowerTools's bin directory and running the 'packer' script.

    Any feedback, beta-testing or else are welcomed.

Dynamic DNS for your GoDaddy domains
No replies — Read more | Post response
by stevieb
on May 17, 2022 at 14:26

    With its API, GoDaddy makes it easy to do dynamic DNS updates for your domain's hostnames. I made it easy to do with Perl with Net::DynDNS::GoDaddy (which uses my new Addr::MyIP to get your current external IP address). I'll give an example, then an example use of the distribution's packaged binary script.

    use Addr::MyIP; use Net::DynDNS::GoDaddy; my $hostname = 'home'; my $domain = ''; my $current_host_ip = host_ip_get($hostname, $domain); my $my_ip = myip(); if ($current_host_ip ne $my_ip) { host_ip_set($host, $domain, $my_ip); }

    Simple. The library requires a godaddy_api.json file in your home directory (MacOS, Unix or Windows, the software has 100% test coverage on all systems) that looks like this:

    { "api_key" : "api_key", "api_secret" : "api_secret" }

    Using the binary we'll install when you install the library, it will prompt you for this information on its initial run:

    > update-ip home Please enter your GoDaddy API key and hit ENTER: ...api_key... Please enter your GoDaddy API secret and hit ENTER: ..api_secret... Updated record for '' from x.x.x.x to x.x.x.x

    ...after the initial run, it won't prompt anymore:

    > update-ip home Not updating the '' record, IPs are the same

    You can specify the IP if you don't want to use your current public-facing one we automatically get for you:

    > update-ip home

    The most useful use for me is to have multiple hostnames ('home', 'office', 'roaming' etc) and just run the program through cron:

    # Home storage server */15 * * * * update-ip home >> /tmp/update-home_cron.log 2 +>&1

    My laptop:

    */15 * * * * update-ip roaming >> /tmp/update-roaming_cron +.log 2>&1


    Usage: update-ip host [ip.addr]

    Have fun!


IndexedFaceSet to 3D lines in two lines of PDL
1 direct reply — Read more / Contribute
by etj
on Apr 17, 2022 at 17:12
    I was digging through some bit-rotted PDL::Graphics::TriD stuff to finish/fix it, and looked at PDL::Graphics::TriD::Logo. It was intended to be used with the non-functional-right-now PDL VRML support, in particular VRML's IndexedFaceSet feature. It had 3D point coordinates, then triplets of indexes into those to describe triangles.

    Gripped - nay, seized - by a desire to see what the logo looked like, I needed to turn that into something the current TriD code can show me. I knew line3d could take a set of 4-point tuples to draw triangles if the 4th point was the same as the 1st. But how to turn points+indexes into that?

    I often say that in PDL, the "right" solution to problems involves slices and dimension-mangling. This was no exception!

    use PDL::Graphics::TriD; use PDL::Graphics::TriD::Logo; $p = $PDL::Graphics::TriD::Logo::POINTS; # dims: xyz, i $i = $PDL::Graphics::TriD::Logo::FACES; # dims: i1to3, ntriangles # 1: duplicate 0-th index onto end of each vector completing triangle $i = $i->append($i->slice('0')); # change to i1to3to1 # 2: flatten indices, slice points with those, restore 4-tuples shape $tri = $p->slice(':',$i->clump(-1))->splitdim(1,$i->dim(0)); line3d($tri); # visualise
    Coda: the logo is just "PDL" in a serif font, given "depth" as if in a stick of rock.

    I'm intending to update the VRML support to:

    1. generalise that plus the OpenGL support of each specific thing (lines, points, etc) to go via an intermediate description to make this easy;
    2. work at all;
    3. switch it to use X3D;
    4. use that to generate updated 3d demos for the PDL website.
    If anyone wants to help, please say so!
Running user-provided JavaScript code
2 direct replies — Read more / Contribute
by cavac
on Apr 11, 2022 at 11:31

    Sometimes you have to allow the end user to provide some (server side) program code, but you don't want them to allow system access. This could be anything, from custom formatting stuff, smart contracts, whatever. The solution is usually a sandbox. Now, Perl itself is a little to powerful and flexible to allow you to do that somewhat safely, but you can use something like the Duktape javascript engine.

    In our case, let's take a look at JavaScript::Duktape. One thing i wanted to implement is "simulated persistance", meaning the JavaScript would be coded as if it is kept in memory, yet the perl program can unload and load it whenever needed. For this, we will define a "memory" object, which the JavaScript can use to keep data in memory.

    Our Javascript program looks like this:

    function initMemory() { memory.counter = 0; } function incCounter(amount) { memory.counter = memory.counter + amount; } function printCounter() { log("Current count is " + memory.counter); }

    To test this, let's write a small test program that uses PageCamel::Helpers::JavaScript. Don't worry about the "PageCamel" part, it's just a helper function in my framework and i didn't have the time to pull it out into a standalone thing. It's pretty much self contained though, code included in this post. Because the PageCamel framework requires a ReportingHandler, for simplicity reasons out test program will just bring it's own.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Making a reloadable module, allowing "live" edits
3 direct replies — Read more / Contribute
by pryrt
on Apr 09, 2022 at 18:44
    I was recently watching this youtube video on a simple PID controller implemented in Python (it was in a watchlist of math-related videos, though his PID was more math-adjacent than math-focused). But instead of focusing on the controller algorithm, I was intrigued by his demo environment, where he was able to update his python code live, and have the demo program automatically incorporate the changes immediately, without reloading the demo program.

    I followed his link to the repo for his demo, where he explains his module and how that portion works.

    "That should be doable in Perl," said I. "And I might even be able to do it." And indeed, after some effort, I could.

    He basically used a class variable to store the state of the module-under-development ("mod"), then used a loop in his demo program that every loop would check the timestamp on the mod's file, and if it was newer, he would store the state, then reload the mod and return a new instance of the mod object initialized to the stored state.

    In my example, which I will replicate in the spoiler, I did something similar, but I just stored the state in the instance of my reloadable object, and had the loop read the state from there and pass it as an option when creating the instance from the reloaded package. (My implementation isn't clean enough for CPAN or anything like that, but as toy, I thought it was a pretty cool usage of Perl, and is good enough for a proof-of-concept.)

    The funny thing is, a few days after I implemented it, as I was finishing up debug of something or other, where I was reloading my program quite frequently, I realized just as I was finishing up, "that would have been a perfect time to use Reloadoadable. DOH!".

    If this has piqued your interest, I would love to see, and learn from, how some of the other monks would implement this. You don't have to use the sine calculator as your example; I just thought it was a simple enough example for the proof of concept. If you wanted to do all the graphics to replicate his PID ship controller instead, by all means... ;-)

XPD - Do more with your PerlMonks XP
5 direct replies — Read more / Contribute
by cavac
on Apr 04, 2022 at 15:37

    As some of you know, i have been playing around with the PerlMonks API to create my own fake internet money. Basically, it's a way to play around with NFT without actually wasting money on that stuff.

    Presenting: XPD

    XPD is the Perlmonks XP Derivative. It's sort of fake monopoly money for PerlMonks. Currently, it supports sending XPD between registered accounts, creating NFT and selling them on the market for a fixed price.

    Edit: If you encounter a bug, post a reply to this post. I have fixed some bugs already, but there are probably more of them around.

    Here is the link:


    Is is real (crypto) currency?
    Nope. This is just a play thing for PerlMonks. Just as PM XP, it has no monetary value. But it's fun.

    Is it blockchain?
    Nope. Blockchains are slow and cumbersome. I use the age old model of central banking. E.g. it's a PostgreSQL database.

    Is it a crypto currency?
    Nope. I mean, i could add checksums and stuff, but what's the point? If you want to make sure i don't mess around, there is a public ledger will all transactions available. You could copy the data. It's currently a bit cumbersome, public API coming soon.

    How do i earn XPD. Mining? Proof of Work?
    Nope. XPD uses Proof of Monk.

    Proof of Monk?????
    XPD is linked to your account on PerlMonks. Be a nice person and help others on PM. This will earn you XP. And earned XP is added to your XPD account. Be naughty and loose XP, and XPD will be deducted.

    How do i register an account?
    Go to You will need a PM account with at least 500 XP, at least 30 posts and a XP-per-post average of at least 4. Fill in the form. Use a password you don't use anywhere else. If you have a password manager that can generate unique random passwords, use that. You username must match your PerlMonks username exactly, because that's how you earn XPD. For validation, you will also temporarily need to add a randomly generated text to your PM homenode.

    How often is generated XP added to my XPD account?
    It's currently set at 72 hour. But, on account creation all XP you already have is added to your XPD account within a minute or so.

    How long does it take to send XPD to another user?
    You select the username and amount, then click "Send". Then the backend checks if have the required funds in your account, does a database insert and it's done. Depending on the other workloads, takes a few seconds usually.

    How does NFT work?
    It's PNG files, 128x128 pixels. It costs 1 XPD to create one NFT.

    How long does it take to create an NFT?
    Similar to sending XPD to someone. You select the PNG file, fill in title and description and hit upload. Then the backend checks (asynchronously) if your file is valid and that you have the required 1 XPD in your account, does a database insert and it's done. Depending on the other workloads, takes a few seconds usually.

    Transaction fees?
    Huh? Why would i charge fees for doing a few database statements that take a few milliseconds. No, the only thing that "costs" a fee is NFT creation. Mostly because i want you lot not completely filling my ancient server with PNG files within the first 24 hours.

    Uhm, yes, coming soon. It's currently missing a few features, like the ability to not crash the server on every other call.

    Selling NFT via an auction?
    Not yet. The backend if half finished, should be online in a few days.

    Smart contracts? Scripting?
    That's in the late design phase. Pretty much anything you can do in the web interface, you will be able to do in the scripting engine. Plus some. You'll be able to buy and sell NFTs, send XPD to someone, bid on an auction, implement a piggy bank, run a Ponzi scheme(*), ...

    (*) It's not real money, XPD is a fun learning experience. If you know how to implement an automated Ponzi scheme, go for it.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Shameless plug and QR japh
2 direct replies — Read more / Contribute
by bliako
on Mar 15, 2022 at 11:29

    My pride for Image::DecodeQR::WeChat I have just submitted on CPAN inspired
    this blitz-style QR japh. Lame as it may be, enjoy.

    Said module is my first to use XS and a significant milestone for
    me as I have managed finally to port OpenCV API into Perl.

    It's been adjusted for PM's rendering particularities and hopefully copy+pasting
    the text from the Download link will produce the correct output.
    Tested on a Linux unicode-enabled terminal. If there is no download link for below code
    then click on Download code below;displaytype=displaycode

    If anyone has suggestions on how to fix this monstrosity
    between code tags let me know
    (edit: pre tags shows the unicode but breaks other things).
    Apropos the QR-code below: ideally I would just use the black brick
    and a white space but unfortunately whatever i do the space gets shrinked
    i tried various unicode spaces but nothing worked, they all got shrinked
    below I am using a thin horizontal line as space which will most likely
    confuse the decoder.


    here is the more readable japh (Above I am "shaping" perl script as a QR code):

    use Text::QRCode; use utf8; binmode(STDOUT, ':encoding(utf8)'); binmode(STDERR, ':encoding(utf8)'); my @a = map { [split//,$_] } split(" ", "anopheles cog, true archon of + junk"); print join "\n", map { y/* /\x{2588}\x{2591}/; $_ } map { join undef, map { $_.$_ } @$_ } @{Text::QRCode->new()->plo +t( join "", map { join("",@$_) =~ m([^^>>]*(.)(.)(.)[<<^^]?(oO(iouuuu))?) and join "", map { ($1+$3==4-$2) ? " " : (42%11-$2==$1+$3) ? uc : +lc } ($a[$2]->[$3]) } map { [m$[950618371>>!42!<<173861059]$g] } "45022250852010350010130232073310513122060312323150640053370 +0710353123331" =~ m$x?.y?.z?.[wrong]?$g )} ;

    bw, bliako

Add your CUFP
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (2)
As of 2022-09-28 18:51 GMT
Find Nodes?
    Voting Booth?
    I prefer my indexes to start at:

    Results (124 votes). Check out past polls.