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").
In my last post (Re^2: Are blessings a new thing?), I talked about Asking Too Many Questions, something I've done at various jobs I've had. Specifically, when I land at a new job, I like to get a little better grounding on What The Business Does To Earn Money (good to know), as well as something about the technical stack, and how the software's organized. I don't apologize for that -- that's how I like to work.
When I started at a desktop publishing software company (in 1987), the CTO was able to draw me a diagram with the various modules on it, showing how the data flowed between them -- and that all made sense. The fact that these modules were actually individual .com files compiled by Turbo Pascal and jury-rigged to run together as a single GEM application was a little scary, but it worked.
I've also worked at a place where the software running things was over a hundred Catalyst modules, and I was left to my own devices to Figure it All Out; there was no overview, no roadmap. To my mind, this is the wrong approach. If you have a code-base of thousands of files and no documentation, are you surprised there are questions?
When a new developer is hired, you want to give them the best possible opportunity to become productive as soon as possible. It also helps if the team that they're going to a) has helpful people who b) have the time and c) the ability to do this orientation. That probably involves finding a couple of basic parts of the system, and walking through how things look in the database, in the code, and from a Support point of view. (Here's how we store information about widgets, here's the code where we figure out what kind of widget's required, and here's how customer service can look up a customer's widget order.)
After asking all of those questions, I do give back, though -- when I had Co-op students at a recent job, I was happy to explain how things worked in the company's software, and talked about the business model, the database layout, how the release management worked, what support did, how we dealt with the flow of information from our partners, and even got a chance to talk about software craftsmanship, from the point of view of a veteran (ugh, I guess that's me).
The right amount of onboarding is when the new developer can look at a ticket, understand what needs to be done, know where to go in order to start developing and testing a solution, and finally present a useful PR to the team. So onboarding is education -- and everyone knows that in software development, education is continuous.
It's that day again, my Monk Day. I'm up to 22 years on this site, and as the title says, probably 25 years noodling around with Perl. What a long, strange trip it's been.
I still host the monthly Perl Mongers monthly meeting in Toronto, and our discussion in November edged over to which editor people used. Like anything else, you use whatever tool works best for you. I'm very impressed by people who use emacs -- it seems insanely complicated. Using tmux with one panel as an editor and another as a bash prompt, is about as complicated as I get.
Perl's the same situation -- if it's a tool you like and can get things done with, great. If there's a new shiny thing you prefer, great. I'm too old to be swayed by people saying, "Oh, no one uses Perl anymore." I use it, thus negating their generalization.
Dare I say .. here's to another 22 years? :)
Edit: OK, I got my quip this time:
Happy Monkday!!1!
You've been here 22 invigorating years.
Did you make a wish?
I don't know if any of my PerlMonks associates have source code or whatever on Google Drive or important email conversations with fellow programmers on GMail, but there is a distinct possibility that some of you have been heads-down coding and are not aware of...
Time is not on your side. ("December 1, 2023 is the earliest a Google Account will be deleted due to this policy.")
And now my editorial:
Here we are on the cusp of A.I. and the world's biggest A.I. / Search engine / Fill in the blanks company has nothing better to do than send us this Christmas present (i.e., a lump of coal)?
Disclaimer: it's clickbait. The plot is curved, solution isn't linear, despite lack of nested loops, -- but fast.
Task 2: Group Hero
Submitted by: Mohammad S Anwar
You are given an array of integers representing the strength.
Write a script to return the sum of the powers of all possible
combinations; power is defined as the square of the largest number
in a sequence, multiplied by the smallest.
Example 1
Input: @nums = (2, 1, 4)
Output: 141
Group 1: (2) => square(max(2)) * min(2) => 4 * 2 => 8
Group 2: (1) => square(max(1)) * min(1) => 1 * 1 => 1
Group 3: (4) => square(max(4)) * min(4) => 16 * 4 => 64
Group 4: (2,1) => square(max(2,1)) * min(2,1) => 4 * 1 => 4
Group 5: (2,4) => square(max(2,4)) * min(2,4) => 16 * 2 => 32
Group 6: (1,4) => square(max(1,4)) * min(1,4) => 16 * 1 => 16
Group 7: (2,1,4) => square(max(2,1,4)) * min(2,1,4) => 16 * 1 => 16
Sum: 8 + 1 + 64 + 4 + 32 + 16 + 16 => 141
Just like last time, this proved quite a challenge!
Most of the time, on reading the Perl Monks name, nothing jumped out at me ...
which forced me to think outside the box, be creative, to have any chance
of concocting a plausible emoji for a typical Perl Monk name ... which I found to be fun.
Without further ado, here's what I've come up with so far:
Name Space by George_Sherston (2001) - what lies behind the names people use at Perl Monks? (lots of replies over many years!)
Updated: Changed Tux from U+1F935 (Person in Tuxedo) to U+1F427 (Penguin) (thanks Tux).
Added George_Sherston's classic node to See Also (thanks Discipulus).
Noticed later that in addition to tachyon there is tachyon-II (don't know if they are the same person though).
To continue my learning of Unicode Emojis, I thought it'd be fun to try to concoct emojis for
some of Perl's famous secret operators.
Here's what I've come up with so far:
Name
Operator
Emoji
Notes
Diamond
<>
💎
nicknamed by Geneva Wall circa 1994
Spaceship
<=>
🚀
nicknamed by Heidi Wall and Randal L. Schwartz (merlyn 🪄) circa 1994
Saturn*
=( )=
🪐
scalar/list context
Kite
~~<>
🪁
a single line of input
Babycart
@{[ ]}
👒🛷
list interpolation, invented by Larry 🧱 (TimToady) circa 1994
*Note: I have chosen not to use the taboo name for this secret operator used at perlsecret
I found this exercise to be surprisingly challenging.
Unable to find an emoji for BooK's quirky Babycart (or a pram),
I opted instead to look for emojis that do justice to the LanX's imaginative suggestion of
Mexican Sledge -- because he visualizes @{[ ]} as a guy with sombrero dragging a sled(ge) uphill.
Please feel free to suggest alternative Unicode emojis for the secret operators
above and to concoct emojis for other
secret operators.
I am inviting all Perl Monks and other Perl contemplatives to help support the idea of a Science Perl track at the upcoming 2024 NA Perl Conference (in Las Vegas).
I'm Canadian, and hockey is in my blood. I've been on skates since I was before I remember.
Being from Toronto, I have my team.
For the last couple of years, I used an app on my phone that would alert me 15 minutes before my teams played (Toronto and Edmonton) so that I had an opportunity to set up recording on my PVR.
In the last two days, I had to refuse the changes in said app's T&S because they wanted info beyond what was needed, so I decided immediately to delete the app. I then of course had to figure out a way to write my own alert software.
I have. As I've done for a long time, I take a problem, and create a Perl solution to produce data from a source that is external. This is no different.
I already have prototype working software. My question is this:
If you're a hockey fan, is there anything specifically you'd want to look up? I already have it pegged as NHL::API, so your feedback will dictate the interface.
When released, I often play around with experimental features;
however, I never use them in production-grade code.
I did the same with the builtin pragma and found many to be useful:
in some cases, I also found the import lists to be quite unwieldy.
When Perl v5.40.0 is released, presumably sometime next year,
I will probably start using many of the stable functions provided by the builtin pragma in production-grade code.
I would like easier to use import lists; accordingly, I'm proposing a number of export tags.
Proposed Export Tags for the 'builtin' Pragma
:bool
Exports: true, false, is_bool.
:weak
Exports: weaken, unweaken, is_weak.
:ref
Exports: blessed, refaddr, reftype.
:round
Exports: ceil, floor.
:stable
Exports all stable (i.e. non-experimental) functions.
perl -d zz.pl
Loading DB routines from perl5db.pl version 1.77
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(zz.pl:5): say "we";
DB<1>
DB<1> l 1.2
1.2 use strict;
DB<2> l
2.2 use warnings;
3.2 use feature 'say';
4.2
5.2: say "we";
6.2: say "just";
7.2: say "need";
8.2: say "something";
9.2: say "to";
DB<2> l 1.1.3.5
1.1.3.5 use strict;
DB<3> l
2.1 use warnings;
3.1 use feature 'say';
4.1
5.1: say "we";
6.1: say "just";
7.1: say "need";
8.1: say "something";
9.1: say "to";
Why does this happen? well it goes back to commit a687059cbaf, which is the one that moves the debugger into lib in Perl 3. The pattern used to capture the line number specification is (\d\$\.)+, which matches all kinds of things, including floating-point numbers, IPv4 addresses, and other junk. The overall pattern used to parse the l command arguments changes over time, but that basic match to extract a "line number" never does.
You may be thinking, "yeah, okay, I see that, but why does the debugger show the floating-point line number?" The reason is that the line number spec is captured as a string. THe debugger stores the source code of the current file in an array whose name is not a valid Perl variable name, and uses the line number spec captured by the l command to index it.
When Perl indexes an array, the index value is converted to an integer if possible, because array indexes have to be integers. The line spec we have is captured and stored as a string, so when we try to index the source array with it, "1.22" becomes the integer 1, and we find line 1. The command uses the value of the index variable (remember, that's still a string!) to print the line number, and so we end up with a floating-point line number.
Now, when we run the bare l command, the string "1.22" is still in the list command's "last line listed" variable, and Perl simply takes that variable and adds 1 to its contents to look for the next line. Since the contents are a string that looks like a floating point number, Perl converts it to a float, adds 1.0 (so we don't downgrade it from a float), and assigns that back to the current line number,so we get lines 2.22, 3.22, and so on.
I've submitted a patch to fix this for 5.40, but it's pretty surprising that we've had this bug for 32 years!
It's a little under 3 years since I created an account here on Perl Monks. For many years, I'd occasionally visited The Monastery thanks to Google leading me here when I asked a Perl-related question - which was quite frequently. But, back in November 2020, I had a few new projects going on and thought I needed to "raise my game". I had no concept of what that actually meant.
My expectation was that I'd learn a few new coding styles, be a bit quicker and, perhaps, a bit clearer.
What has actually happened, and continues to happen, is that my whole approach to writing code has changed...drastically!
Allow me to illustrate by way of an example...
Just this week I was writing some code for the admin part of my partner's website Pawsies. We need to be able to upload pictures of dogs that we look after, and it's helpful if those pictures are square so they display consistently.
The whole website uses Template - something I discovered in The Monastery. The web scripts are in their own directory and not mixed up with the other site files, again a learning from The Monastery. The upshot is sites that are easier to navigate, easier to link to as everything is not in the cgi-bin and easier to maintain.
However, it goes much further than that.
In the past, if I wanted square images, I would have hard-coded the logic to produce them into the script that needed them. But this week, instead I wrote a module to do only that operation. It is where my thought process started, it was not an afterthought. The design started with deciding exactly what it was supposed to do and by jotting down how I would know if it was successful. The basis of a test!
I then looked to see if there were any extra generalisations that could be made to make it more useful to other people or when I reuse it elsewhere. So, a resizing parameter was added to change the size of the square image and a position parameter was added to determine where abouts the square is taken from in the original image.
Only then was the code written followed by the tests...
Once the tests all ran fine, it was bundled up and uploaded to CPAN for all to use. Currently as a dev release so I get some test results before the production release. It's all looking good...
Before joining The Monastery this would have been a bit of messy, but functional code locked away somewhere in a difficult-to-maintain script. I considered CPAN modules to be for other, superior "proper" coders...not for me. Now I look for the best way to do it for my needs now, my needs in future when I come to maintain the code or need similar functionality and for the needs of the wider Perl community as The Monastery has shown me that I have something to contribute as well as to learn.
Watch out for a testing question coming soon - one of the tests for Image::Square required visually inspecting the output image and I don't know how to convert that into a usable test...see, lots more to learn and that's something I fully embrace!
Thank you to everyone who has helped, inspired, questioned and critised me over the last 1000 post - it really is appreciated 👍
Being our venerable halls quiet nowadays I propose this meditation to share ideas of programs, modules and everything you want we have no time enough to develop them further.
In my world ideas have no copyright and should instead circulate freely as there is the chance they are grasped by an enlightened soul who can squeeze the best from them.
Even more: there are amateur programmers with nice ideas and professional ones with few ones. It is not something to complain about, we are different brains with different skills, inclinations and.. free hours :)
I'd like to see at least some demo code for these ideas with the goal well explained as any possible path of implematation or critical parts, not just: /I'll save the world with a oneliner/.
We can use a tag for these post like [NTF] (No Time For) and post them in reply at this post or as new Meditation.
I'll start with a first one if are ok with this ..nice perl idea :)
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.
After recently installing perl v5.38,
I stumbled upon some cool improvements to Perl's built-in try/catch syntax while watching the excellent
What's new in Perl v5.38
youtube talk, delivered by Paul "LeoNerd" Evans at TPRC 2023 Toronto.
perl v5.36 added "finally" blocks to try/catch, also inspired by Syntax::Keyword::Try
perl v5.36 added use feature 'defer', allowing you to create defer blocks that run at the time that execution leaves the block it's declared inside (which seems to be inspired by the classic RAII programming idiom)
To get a feel for how all this works in practice, I created a simple example,
consisting of two files in a scratch directory, TestTry.pm and trytest.pl, shown below.
TestTry.pm
package TestTry;
use strict;
use warnings;
print "TestTry: module load\n";
sub life {
my $n = shift;
defined($n) or die "error: no argument provided";
print "TestTry::life n='$n'\n";
$n =~ /^\d+$/ or die "input error: '$n' must consist of digits only
+";
$n == 42 or die "Sadly there is no meaning in your life (n=$n)
+";
print "TestTry: congrats, your life has meaning!\n";
print "TestTry::life end\n";
}
1;
# trytest.pl - a simple test of new perl 5.38 try syntax:
# Put TestTry.pm in same dir as trytest.pl and run with:
# perl -I . trytest.pl
# Note: use v5.38 implies use strict and warnings
use v5.38;
# use feature 'try'; # throws 'try/catch is experimental' warnings
use experimental 'try';
use TestTry;
sub do_one {
my $number = shift;
try {
TestTry::life($number);
}
catch ($e) {
chomp $e;
print "trytest: caught '$e'\n";
}
finally {
print "trytest: in finally block\n";
}
}
print "trytest: start\n";
do_one("invalid");
do_one(13);
do_one(42);
print "trytest: end\n";
With that done, assuming you have perl 5.38 installed, you can run:
$ perl -I . trytest.pl
TestTry: module load
trytest: start
TestTry::life n='invalid'
trytest: caught 'input error: 'invalid' must consist of digits only at
+ TestTry.pm line 11.'
trytest: in finally block
TestTry::life n='13'
trytest: caught 'Sadly there is no meaning in your life (n=13) at Test
+Try.pm line 12.'
trytest: in finally block
TestTry::life n='42'
TestTry: congrats, your life has meaning!
TestTry::life end
trytest: in finally block
trytest: end
I really like this new try/catch syntax and am looking forward to Perl
providing built-in exception handling without having to install CPAN modules,
such as Try::Tiny and TryCatch.
Remembering the smartmatch/Switch debacle, I'm also a fan of this new gentler way
of introducing experimental new features into the Perl core.
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).