If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
JIRA-Client-Automated stopped working for me, Atlassian modified the API's. The requested API for searching issues has been removed.
3 direct replies — Read more / Contribute
by gargle
on Sep 18, 2025 at 02:29

    Not really a question, but more like a warning for other users of JIRA-Client-Automated. If this notification doesn't belong here, then please let me know. It's been too long ago since I last visited perlmonks.org, sorry!

    I'm using all_search_results in JIRA-Client-Automated to filter out all issues that are assigned to me. The code is here below. The call doesn't work anymore.

    I already logged bug https://rt.cpan.org/Public/Bug/Display.html?id=170062

    my @open_issues = $jira->all_search_results( "(((assignee = " . $accountId . " or assignee = 557058:03251bcc-c6a3-4137-a7f0-d5c63be68d1d9 +)" . " and project != \"ST - Dev Support\")" . " or ((assignee is empty or assignee =" . " 557058:03251bcc-c6a3-4137-a7f0-d5c63be68d1d9 or assignee = + " . $accountId . ") AND project = \"ST - Dev Support\")) AND status != Done" . " and status != Cancelled order by created DESC");

    This is the error I am getting:

    Unable to POST /rest/api/latest/search/: 410 Gone{ errorMessages => [ "The requested API has been removed. Please migrate to the /rest/a +pi/3/search/jql API. A full migration guideline is available at https +://developer.atlassian.com/changelog/#CHANGE-2046", ], errors => {}, } for request: { fields => ["*navigable"], jql => "(((assignee = 557058:488e7764-b837-4c11-974d-ec9115f47e26 or + assignee = 557058:03251bcc-c6a3-4137-a7f0-d5c63be68d1d9) and project + != \"ST - Dev Support\") or ((assignee is empty or assignee = 557058 +:03251bcc-c6a3-4137-a7f0-d5c63be68d1d9 or assignee = 557058:488e7764- +b837-4c11-974d-ec9115f47e26) AND project = \"ST - Dev Support\")) AND + status != Done and status != Cancelled order by created DESC", maxResults => 100, startAt => 0, } at ./checkJiraIssues.pl line 57.
    --
    if ( 1 ) { $postman->ring() for (1..2); }
OT: Stupid User Interfaces (Part 2)
3 direct replies — Read more / Contribute
by afoken
on Aug 23, 2025 at 07:53

    (Continuing the old rant OT: Stupid User Interfaces)

    How hard can it be to open a door?

    This week, I had to travel in a regional train, a quite modern Stadler KISS train operated by DB Regio (Deutsche Bahn). Very unsurprisingly, it has electrical door openers to enter and leave the train. A big round button surrounded by red and green LEDs. Wait until the green LEDs are on, press the button, and the door will open. Easily done even by a three year old kid. I'm old enough to remember trains where you had to push the door open, requiring quite a lot of force.

    These modern doors (and that's not limited to the KISS) tend to fail quite often, so DB Regio uses large yellow stickers on the door windows telling you that the door is unfortunately broken and that you should use one of the other doors. Well, that's annoying. You would expect that a door that is used daily by literally thousands of people in the not too extreme weather of Germany to be designed to withstand that use for more than a few months. But that's not the point. The yellow sticker tells you that the door won't open, period.

    The KISS train has doors between the segments, designed as a kind of "leaky airlock", with a sealed electric sliding door opened by a small illuminated button on the one side and an unsealed glass swing door on the other side. A very strange design, causing a lot of noise and draught near the glass door, the glass door needs a lot of room in a small area to swing open, and it needs some force to open. Two sliding doors, as in much older trains, would have been the smarter solution.

    Now imagine that ugly yellow sticker of shame on the electric sliding door, telling you to use one of the other doors, and the "open" button not being lit. Are they expecting me to climb out of the train at 100 km/h, and enter the next car through one of the outside doors? Probably not. There is a yellow sticker of shame on the door, so it won't open, period.

    Or will it? After abour half an hour, someone entered the car through the door. So my thought was "poor guy, now you are trapped in this car, too". I was expecting that only the open button on my side of the door was broken. And he went back to his car, through the door with the yellow sticker. So, yes, the door could not be opened electrically. But it still has handles, and can be opened with a little bit of force. D'oh! I could have travelled in a car with way less people if I had actually tried the handles.

    How hard can it be to open a door, again?

    Remember that big round buttons with the LEDs, that can open the door when the green LEDs are on? Three of the four cars in a KISS train are equipped with a large lavatory, usable even if you need a wheelchair. One of the big round buttons with the red and green LEDs is mounted next to the door of the lavatory, with the green LEDs permanently on. Guess what happens if you press that button.

    If you are unlucky, a voice recording tells you that the lavatory is out of order. Or it tells you that the lavatory is currently in use. In both cases, the door won't open. But, if the lavatory is unused, and you press the button, the voice recoding will tell you exactly that. The door won't move a bit.

    This button is not a door opener. It is a method of identifying frequent travelers. If you know the KISS trains, you completely ignore the button and look at the traditional red "WC" light. If it is off, you can enter the lavatory by pulling hard on the door handle. If you don't know the KISS trains, that button will make you look like a fool who does not know the red light.

    The official purpose of the button a replacement for the red light for blind and visually impaired persons.

    Too bad noboby really thought about the lavatory door. It is huge, to allow entering the lavatory in a wheel chair. Good. But it requires a lot of force to open and close. Little kids can't open the door, and even some adults have problems opening and closing it. So, where is the electrical door opener wired to the infrequent traveler identifier button?

    How hard can it be to track working time?

    German law forces us to track working time, and that's a good thing. We don't need to track anything more than "working" or "not working". A time stamp clock at the entrance would be sufficient. Except that we sometimes work from the home office, or spend an entire day at a client. Legally, we could even get away with hand-written notes. The law just requires that the working time is recorded, not how.

    We work for different clients, sometimes with a fixed price, sometimes we are being paid by the hour, sometimes both at once even in the same project (don't ask). So we recently decided to use a cloud-based time tracking app, which can run in a web broswer, in a desktop application (which is just a browser without an address bar), or in an Android or iOS app (which propably also is just a browser without an address bar).

    • You can not change your password. Period.
    • Logout button is hidden behind two menu layers.
    • There is a permanent reminder (in the browser) to install the desktop application, that you need to click away every single time you log in.
    • The desktop application refuses to start after installation ("This is not a Windows application")
    • The Android app is simply unusable. It has the same visual interface as the website, but requires completely different handling than all other Android apps (drag instead of tap for a new record, no way to edit records, and so on).
    • You can track time only in a calender view:
      • Short jobs are so tiny in the default zoom level that you can not see them
      • Long jobs require zooming out and/or scrolling.
      • You need to open a popup to fix start and stop times, or use zoom and drag-and-drop to adjust start and end times
      • Zoom requires you to use a special control on the page, you can not use Ctrl + mouse wheel or keyboard shortcuts
    • You are not allowed to track times of one minute or less. (Not a company policy, the software prohibits that.)
    • There is no list view of tracked time, period.
    • About half of the screen width is reserved for unused features, while at the same time project names are cut of due to width restrictions.
    • The default for the "paid by the hour" switch can be set by the admins for each project. In mixed-payment projects, you may need to change that switch. Which causes more trouble:
      • Admins can't change switch in tracked time, so lists need to be written and users have to toggle that switches for an entire a month.
      • Resuming a job resets the switch to the default value instead of keeping the switch as is

    And that's only the interface for the "worker bees". I did not even bother to look at the admin stuff, or the reporting that is completely useless unless you are working self-employed.

    All we really need is a simple, five-column table:

    • Start time
    • End time
    • Project (from a lookup table)
    • paid by the hour (checkbox)
    • Short description for the invoice

    Invisible to the user, a sixth column should track the user ID, so working times can be properly summed up, and users see only their own time records.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Printing maps with LeafletJS & a potent way to html2pdf
No replies — Read more | Post response
by bliako
on Aug 20, 2025 at 17:47

    Recently I needed to display a map with some polygons, markers and popups on it. I wanted to have both an interactive map but also be able to create a hardcopy from my linux's terminal via a script in a headless server.

    I found a solution which satisfies both requirements. Have the interactive map be from the HTML produced by LeafletJS and then spawn a headless browser (thank you WWW::Mechanize::Chrome & Corion!!) and take a screenshot of the map, via a script from any headless server.

    To me, at least, the screenshot part sounds like a very roundabout way of getting a hardcopy of a map (a PDF or PNG) but after researching this for a few weeks, I realised that this is how it is done in R (and in the serpent world, it is called htmlwebshot).

    Building on WWW::Mechanize::Chrome's screenshot functionality and on a conversation I had with LanX some years ago on how to inject JS into a mechanized browser and manipulate the DOM with it I have now published WWW::Mechanize::Chrome::DOMops which finds/deletes elements of the current DOM of your mechanized browser and then on top of that, WWW::Mechanize::Chrome::Webshot which takes a screenshot of your browser contents onto a local file. In short, it renders a URL or a local file onto a, possibly headless, mechanized browser (with all encompassing CSS and JS included), allows some settle time, optionally removing some DOM elements which clutter the view and takes a screenshot of what's currently rendered. I think this is as good as it gets for html2pdf. I mean the browser is the final arbiter on how html renders right? (well, sort of).

    https://leafletjs.com/ is really very good at displaying map tiles, images/satellite or vectors, from various sources (e.g. OpenStreetMap for navigation vector maps or ArcGIS/ESRI for satellite images, both free). It is also very easy to draw polygons, markers, etc. on top of the map using map coordinates. And then allows you to move/pan/zoom interactively. Really cool software. Alas in Javascript.

    And so, in the below script I combine both to get both a self-contained HTML (it requires lefleat.js external dependency) of an interactive map as well as a printout in the form of PDF/PNG.

    Caveat: the output PDF contains only part of the view (increasing the dpi perhaps?) whereas the PNG contains everything the browser window contains. So, a PNG is output instead.

    PS: I had in mind to create a Just another Perl Hacker all over Africa but the polyline is quite some bytes long and I will spare you the bandwidth. Just imagine Just another Perl Hacker sprayed all over the globe.

    PS2: Geo::Leaflet does a good job at exposing the basic functionality of LeafletJS via Perl. But there are lots more features and options for your map. I propose that once you have a basic HTML map, to template it and keep adding more features there. You do not need to keep using Geo::Leaflet. Check the script's output HTML file.

    # by bliako for perlmonks 21/08/2025 use Geo::Leaflet; use FindBin; use File::Spec; use WWW::Mechanize::Chrome::Webshot; my $lat = 11.1; my $lon = 22.2; my $outbase = 'hack'; my $map = Geo::Leaflet->new( id => "myMap", center => [$lat, $lon], zoom => 3, ); # the tiles are coming from: $map->tileLayer( # navigation vector tiles #url => 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', # satellite images url => 'https://server.arcgisonline.com/ArcGIS/rest/services/World_ +Imagery/MapServer/tile/{z}/{y}/{x}', options => { maxZoom => 19, maxNativeZoom => 23, #attribution => 'openstreetmap', attribution => 'esri', }, ); $map->polyline( coordinates => [ [9.0, 20.0], [11.3, 23.1], [12.1, 19.4], ], options=>{color=>'red', weight=>'5'} ); my $map_html = $map->html; my $outdir = $FindBin::Bin; my $map_html_outfile = File::Spec->catfile($outdir, $outbase.'_map.htm +l'); my $FH; open($FH, '>', $map_html_outfile) or die "failed to open file for writing html '$map_html_outfile', +$!"; print $FH $map->html; close $FH; my $map_pdf_outfile = File::Spec->catfile($outdir, $outbase.'_map.png' +); my $shooter = WWW::Mechanize::Chrome::Webshot->new({ 'settle-time' => 10, 'resolution' => '2000x2000', }); my $local_uri = URI->new('file://'.$map_html_outfile); $shooter->shoot({ 'output-filename' => $map_pdf_outfile, 'url' => $local_uri->as_string, 'remove-DOM-elements' => [ {'element-xpathselector' => '//div[id="leaflet-control-container +"]'}, ], 'exif' => {'created' => 'by the shooter'}, }); print "$0 : done, map saved to PDF '$map_pdf_outfile'\n";

    bw, bliako

Improving core performance with SIMD
2 direct replies — Read more / Contribute
by phizel
on Aug 13, 2025 at 08:22
Anyone migrated to the new 'class' way of OOP?
6 direct replies — Read more / Contribute
by stevieb
on Aug 07, 2025 at 05:28

    ikegami recently posted a question that eventually led me to the new perlclass documentation.

    I haven't been following along that much, but it seems intriguing.

    I have a ton of OOP code using the old-school bless() way of doing things, and after a cursory look at this documentation, my gut says that I shouldn't change anything. There have been so many iterations of OOP modules and such, it just seems that it'll keep changing over and over again. However, with that said, I've been around a long time, and considering almost all of my code will still run on 5.8, Perl is known for its backward-compatibility.

    What are your thoughts on this new way of Perl OOP development? Are you embracing it? Are you sticking with the old? For long-time developers, are you considering transitioning?

    Legitimately curious,

    -stevieb

Yet Another Program on Closures ~ Steven Lembark ~ TPRC 2025 - YouTube
1 direct reply — Read more / Contribute
by LanX
on Jul 30, 2025 at 11:37
Perl and the Unix Philosophy (Keynote) ~ David Both ~ TPRC 2025 - YouTube
No replies — Read more | Post response
by LanX
on Jul 27, 2025 at 11:30
Success in getting a boost for building extension modules using distcc
No replies — Read more | Post response
by Intrepid
on Jul 07, 2025 at 12:22

    Hello worthy Monks and Nuns. I'm writing today because on Saturday (a couple days ago) I had a personal triumph: I got the tool distcc working across my LAN; at present providing support to a laptop running Linux from a desktop also running Linux. The speed-up in intensive compilations of some Perl extension modules is noticeable, for example, in building modules in the the Digest:: namespace, particularly with one module (I don't recall for sure which one) which had dozens of XS files to convert to C and compile.

    I had distcc set up on my client machine (the laptop) months ago, at that time having made the little farm of symlinks recommended as the way to drive distcc in turn to drive gcc. What I didn't have working and couldn't get a handle on was the setup on the host(s), where the compilation is performed; in the file /etc/distcc/clients.allow I needed to define client hostname specifications in CIDR notation (for me, 192.168.1.0/24) for "allowed clients." Without that set up right, I kept seeing messages from distcc saying connection refused or variants on that.

    Obviously big jobs like building the Linux kernel or Samba are where having something like distcc is really helpful. But it's just plain cool to have it working for Perl tasks too.

        Soren

    Jul 07, 2025 at 16:22 UTC

    A just machine to make big decisions
    Programmed by fellows (and gals) with compassion and vision
    We'll be clean when their work is done
    We'll be eternally free yes, and eternally young
    Donald Fagen —> I.G.Y.
    (Slightly modified for inclusiveness)

Back to programming? A gossamer hope to automate SSL cert renewals
4 direct replies — Read more / Contribute
by Discipulus
on Jun 25, 2025 at 05:47
    Hello nuns and monks,

    As many of you know nowadays I'm not programming for my work since years. In the not so recent past I've made some stuff for my pure pleasure or just to help a bit here.

    The programming communtiy did not cried for this :)

    At work I suffered a fistfull of company mergeS and now I'm relegated to boring tasks as boring can be to renew SSL certificates.

    Our IT world runs as a mad without a precise destination and strange things happens, as it happened that CA/Browser Forum decided to reduce SSL certificate duration in this way:

    • after March 15 2026: validity reduced to 200 days
    • after March 15 2027: validity reduced to 100 days
    • after March 15 2029: validity reduced to 47 days <--- O_O
    But, as we say in Eataly, "not all evils come to harm" and there is a remote possibility I can convice the whole pyramid of my bosses that I can setup some Perl code at least to renew certificates and maybe somewhere install them too.

    For sure bosses will complain with: "hey, we have a Dev Dpt here" ..but they act at geological times, and if they insist I can at least propose to setup a demo or better the core functionality we'd like to have distilled into a Perl module (a group of..). This point is important.

    I cant let this small chance to fade out, so I must be prepared ( dormitare de fuga cogitante vetat ).

    Nowadays Macaroni Group uses Digicert for almost all SSL certificates. They have some APIs for their CertCentral (the new, shiny, fancy, fashion web interface). I asked to tech support if they have also a SandBox environment (money is involved) and they didnt even know the term.. :(

    So here I'm, after this long rant, to ask you how to plan my strategy in the right way.

    • A base module to use automation-api let say Digicert::Automation. Maybe there is the need to have a base module for the general API: service-apis Ideally this module should be public even if I already fear the testing part.
    • A serie of other modules using the above, private to the company I work for, to manage: customers, contacts, mail, orders info e renewals etc.
    • a small DB to record customers, their certificates, contact informations, internal contact.. I'd like to keep this as small as possible, ideally an SQLite one.
    • a CLI tool to inspect orders, renew certificates etc.. using the above modules and DB.
    • ?? a web interface? I'd skip this part, but it depends how bosses see it.
    • a cron job to run daily using the above CLI to monitor orders and automatically renew expiring ones.

    What I'd like from your part at the moment are: suggestion on the big picture, its design implementation, on hoW to start coding the base module, previous experience in this.. and whatever you think is important to take in count.

    Hopefully this is the first of many request on the matter.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
1. Go compare! Guardian's algortithm riddle and mathematical proof
3 direct replies — Read more / Contribute
by LanX
on Jun 07, 2025 at 19:34
    FWIW: It's not too off topic because it's about an algorithm

    The Guardian asked in a recent Monday puzzle for an optimal strategy to find the smallest and the biggest in a deck of 100 cards.

    https://www.theguardian.com/science/2025/may/12/can-you-solve-it-are-you-craftier-than-a-cat-burglar

    (It's not the rope riddle)

    While my strategy was optimal like the proposed solution, they claimed the formal proof that there can't be any better solution to be "too technical" to be published there. (Pierre de Fermat giggles in his tomb).

    The attempts in the comment section didn't impress me either.

    Anyway I spent the last hours figuring out an elegant proof for a general formula of any numbers of cards.

    But the comment section there is long closed and I thought the local crowd here would like to try their best too ...:)

    So here the task again: (copied from above link)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

    ¹) It's quite rich to ask for an optimal strategy without presenting one...

AI in the workplace
10 direct replies — Read more / Contribute
by talexb
on May 30, 2025 at 22:13

    I sit on a Program Advisory Committee for a local college as an industry representative, and at next week's meeting we're going to be asked about 'AI in the workforce'. They'll be asking about specific areas, a) How organizations are integrating AI tools, b) Whether AI can be used as a supplement or replacement, and c) What implications AI has for productivity and skill sets.

    What do you think college graduates should know about AI? How much do you think they should rely on AI tools? Is vibe coding a real thing?

    Alex / talexb / Toronto

    For a long time, I had a link in my .sig going to Groklaw. I heard that as of December 2024, this link is dead. Still, thanks to PJ for all your work, we owe you so much. RIP Groklaw -- 2003 to 2013.

Proving Veritasiums riddle using Perl
4 direct replies — Read more / Contribute
by cavac
on Apr 30, 2025 at 15:36

    About two years ago, Veritasium posted The Riddle That Seems Impossible Even If You Know The Answer on Youtube. Today i was rewatching that video, because after seeing it initially i had some doubts, and it was a bit of an itch i finally decided to scratch.

    The basic riddle goes something like this (watch the video for a much more coherent explanation AND the solution):

    1. You have 100 prisoners, each with a number.
    2. There is a room with 100 (numbered) boxes, and every prisoner number is in one random box.
    3. Prisoners enter the room one by one
    4. Each prisoner can open 50 boxes and search for their prisoner number.
    5. Each prisoner has to leave the room exactly as he found it.
    6. If ALL prisoners find their own number, everyone goes free.
    7. If even a single prisoner fails to finds his number, everyone stays in jail.
    8. Prisoners can decide on a tactic BEFORE the event, but can't communicate in any way DURIN the event.

    If prisoners just do random sampling, their chances are 0.5**100 = 0.0000000000000000000000000000008.

    Is there a better tactic? (Rest of the post in spoiler tags if you want to have a go on the problem yourself).

    According to Veritasium, the solution is this: Every prisoner picks the box with their number on top (=prisoner 42 picks box 42) to start with. He opens the box. If the box doesn't contain his number, he then picks the box with THAT number to open next, and so on. This improves the chances for the whole group to 0.31 (31%).

    I'm not good at doing mathematics proves, or writing scientific papers. My one (and only) real talent is crunching data with software. But, wait. This IS a problem you can simulate! No math degree, no AI, just throw some raw CPU cycles at the problem and see if we can get a reasonable match to the results Veritasium posted.

    #!/usr/bin/env perl # https://www.youtube.com/watch?v=iSNsgj1OCLA use v5.40; use strict; use warnings; use diagnostics; use Array::Contains; my $PRISONERCOUNT = 100; # How many prisoners my $OPENBOXES = $PRISONERCOUNT / 2; # Every prisoner can open half the + boxes my $LOOPCOUNT = 10_000; my $DEBUG = 0; STDOUT->autoflush(1); my @results = (0, 0); for(my $l = 0; $l < $LOOPCOUNT; $l++) { if($DEBUG) { print "== SIMULATION $l ==\n"; } elsif($l % 100 == 0) { print "== SIMULATION $l of $LOOPCOUNT ==\r"; # non-debug: over +write the line without scrolling } $results[simulate()]++; } print "\n"; print "Success: ", $results[1], "\n"; print "Fail: ", $results[0], "\n"; print "Fail rate: ", $results[0] / ($results[0] + $results[1]) * 100, +"%\n"; sub simulate { my $boxes = generateBoxes(); DumpBoxes($boxes) if($DEBUG); print "Checking prisoner " if($DEBUG); for(my $i = 0; $i < $PRISONERCOUNT; $i++) { print $i, " " if($DEBUG); if(!checkBoxes($boxes, $i, $OPENBOXES)) { print "Failed!\n" if($DEBUG); return 0; } } print "OK\n" if($DEBUG); return 1; } sub generateBoxes { print "Generating boxes...\n" if($DEBUG); my @boxes; while(scalar @boxes < $PRISONERCOUNT) { my $prisoner = int(rand($PRISONERCOUNT)); if(!contains($prisoner, \@boxes)) { push @boxes, $prisoner; } } return \@boxes; } sub checkBoxes($boxes, $prisoner, $count) { my $currentbox = $prisoner; while($count) { my $val = $boxes->[$currentbox]; # Get content of current box if($val == $prisoner) { return 1; } $currentbox = $val; $count--; } return 0; } sub DumpBoxes($boxes) { print "---- BOXES -------------\n"; for(my $i = 0; $i < $PRISONERCOUNT; $i++) { print $i, " => ", $boxes->[$i], "\n"; } print "---- LOOPS -------------\n"; my @seen; for(my $i = 0; $i < $PRISONERCOUNT; $i++) { my $currentbox = $i; my $count = 100; my $ok = 1; my @current; while($count) { if(contains($currentbox, \@seen)) { $ok = 0; # Part of already known loop last; } push @current, $currentbox; my $val = $boxes->[$currentbox]; if($val == $i) { last; # Loop done } $currentbox = $val; } if($ok) { print join(' ', @current), "\n"; push @seen, @current; } } print "------------------------\n"; return; }

    And it seems to be a relatively good match:

    $ perl simulate.pl == LOOP 99900 == Success: 31139 Fail: 68861 Fail rate: 68.861%

    And if we activate $VERBOSE, we can get a simple view of those loops Veritasium was talking about:

    ---- LOOPS ------------- 0 72 86 73 80 1 96 19 83 91 47 75 18 53 3 50 24 81 59 38 23 44 67 39 55 65 2 20 45 98 84 89 63 93 46 58 68 28 56 64 78 6 87 52 8 82 97 34 31 85 7 +9 12 41 48 70 66 37 5 49 33 51 15 57 54 69 90 26 43 14 94 76 9 88 40 4 42 25 99 27 77 16 10 74 36 22 7 13 71 61 62 11 95 21 17 30 29 32 35 60 92 ------------------------

    Frankly, even having programmed a full simulation of the solution myself, it still absolutely boggles my mind that this actually works at all. Maths is weird.

    PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
    Also check out my sisters artwork and my weekly webcomics
Do Androids Dream of Electric Sheep? Control your smartphone from the desktop
2 direct replies — Read more / Contribute
by bliako
on Apr 19, 2025 at 06:52

    Brothers and sisters, fellow Monks (lend me your ears),

    I have recently discovered that there is still quite a lot of hope for using a smartphone as a tool for empowering people and not enterprises. Android is providing a very potent program: the Android Debug Bridge (ADB) which communicates with an Android device connected to your desktop (via USB or in same wifi network). With this program, one can tell the device to wake up, to enter the passcode of the screensaver, to navigate to the home screen, to open apps, to close apps, to swipe, to click, to input text. To get readings from sensors, to get a screenshot or a screenvideo and finally to dump the current screen's UI as XML which can then be parsed to find widgets of interest, e.g. a button to click, a textbox to enter text, a list of contacts, etc.

    The two main problems with controlling your smart device in such a way are: 1) Android API differences between versions, so standard apps or widgets are named differently. 2) Android remembers to notify you about something when in the middle of controlling an app and steals the focus. But neither of these problems is insurmountable.

    The idea of controlling a device from my desktop is very appealing. In fact, I do not use a real device but an emulator (A note of warning here, better use an emulator or an unimportant phone).

    At first a friend wanted to keep tapping on an app in order to gain some points for an idiotic competition. Then I wanted to send viber and skype messages from the command line of my linux terminal. And so I have set out to make a thin wrapper to the ADB for Perl. There are a lot of such wrappers for a lot of environments but I did not see one for Perl yet. So here it is : Android::ElectricSheep::Automator

    use Android::ElectricSheep::Automator; my $mother = Android::ElectricSheep::Automator->new({ 'configfile' => $configfile, 'verbosity' => 1, # we already have a device connected and ready to control 'device-is-connected' => 1, }); $mother->tap({position=>[1,2]}); use Android::ElectricSheep::Automator::Plugins::Viber; my $vib = Android::ElectricSheep::Automator::Plugins::Viber->new({ configfile=>'config/plugins/viber.conf', 'device-is-connected' => 1 +}); $vib->open_viber_app(); $vib->send_message({recipient=>'My Notes', message=>'hello%sMonkees +'}); $vib->close_viber_app();

    bw, bliako

A Perl interpreter written in Perl?
4 direct replies — Read more / Contribute
by harangzsolt33
on Apr 15, 2025 at 22:35
    Has anyone ever written a pure perl interpreter written entirely in Perl?

    And of course, I know, you could do read_file() into $string and then eval($string) but that's not what I mean. LOL

    Has Perl ever been reproduced in Perl?

RFC: a meditation on Module::List and Module::List::WithPath
2 direct replies — Read more / Contribute
by Intrepid
on Apr 03, 2025 at 19:57

    Hello erudite Monks and Nuns,

    I found a CPAN module recently that really makes me happy. As a habitual serial installer of anything from the CPAN that looks interesting, I sometimes forget what I have installed before I can start to write some code using it. Enter Module::List; which showed up as "recent" on MetaCPAN with the release of version 0.004. There is also a close relative, let's call it a talented nephew, Module::List::WithPath, which is based on Module::List and adds the ability to discover the filesystem path location of each module found. At the time of this writing, module Module::List::WithPath is at version 0.003002.

    But we're ahead of ourselves. What Module::List does is a lookup on the prefix given as an argument to the sole subroutine in the module, list_modules, returning differing information depending on the options given (as an anonymous hash) -- for example, all the installed module names with that prefix (I won't describe every bit of the functionality or API since that's all right there on MetaCPAN for the reader to peruse). I'll make the observation that the API is a bit unusual: instead of providing a separate subroutine (either exported or not) for each kind of data sought, the module provides options (as just described above). The most interesting option (imho) is the first listed in the POD, list_modules. The return data is a hash reference with keys corresponding to module names found in the abstract namespace (regardless of where the modules were found on the filesystem). The values of the hash elements are in each case the empty string. In the case of the talented nephew, Module::List::WithPath, the element values are, instead, the filesystem locations of the modules found. Very nifty.

    I just find these modules really neat and they fill a gap that I've been feeling for a long time. Quirks (arguably) of implementation aside, the modules have enabled me to write simple short scripts to query my Perl installation and discover what has lain there, waiting but forgotten.

    Apr 03, 2025 at 23:54 UTC

    A just machine to make big decisions
    Programmed by fellows (and gals) with compassion and vision
    We'll be clean when their work is done
    We'll be eternally free yes, and eternally young
    Donald Fagen —> I.G.Y.
    (Slightly modified for inclusiveness)


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


  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.