Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Meditations

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

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
Libraries and security
No replies — Read more | Post response
by davies
on May 23, 2022 at 10:25

    An article in today's Register, https://www.theregister.com/2022/05/23/npm_dependencies_vulnerable/ has got me thinking. One quote from it is "These 2,415 people with these email addresses are currently more trusted than your own software engineers as they can effectively run any code they want on your production infrastructure without review from anyone". When the Log4J vulnerability appeared, I found out (I hardly ever use Java) that the offending module could be in any .jar without it being obvious to the programmer. At least, when I install a CPAN module, I can see a list of the modules it brings with it, even if I don't usually pay enough attention. But sometimes I need to be very security conscious.

    Looking for vulnerabilities in CPAN took me to https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=cpan. There's not a lot there, and many of them are closed in the latest version. But looking at one of them, https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4184, I see that the module was updated last month but that there is nothing in the changes file to indicate that the vulnerability has been addressed even though it's nine years old. Nor is there anything in the docs even acknowledging the existence of the vulnerability.

    The changes file does, however, reveal another worry.

    1.148 Thu Nov 16 10:21 2006
    - Debian has chosen to distribute their own Data::UUID, which has a different interface and breaks other modules.

    What, then, do people do in the real world? Are checks for CVEs enough? Do people do code reviews of every module they use in every language? It sounds beyond the bounds of reasonability to me. Are there certifications for modules (and if so, who certifies the certifiers - that old question)? I know people who prefer to install Perl packages on Debian via apt because it makes them easier to delete, but the quote above makes me fear that the CPAN and apt packages need not be the same.

    Regards,

    John Davies

RFC: Creating Dancer2 validation plugin.
3 direct replies — Read more / Contribute
by AlexP
on May 04, 2022 at 10:30

    Hello monks, this is requests for comments, so if you are interested in this topic, please leave any.

    Preface

    Dancer2 is a lightweight framework that provides us with rich routing and serialization features out of the box. The rest is left to the developer, including working with the database, models and data in general.

    When working with data, especially received from a user, you want to be sure of their consistency. In other words, I don't want to get a number where the username should be and the word in the age field (like age => twenty).

    Perl is a language with very powerful regular expressions and many hackers use them. However, this approach has the following disadvantages:

    • It is not declarative, you need to validate all fields manually
    • It's hard to reuse
    • Code is cumbersome and hard to read

    Instead of writing if ($age !~ /^\d+$/) {…} else {…} and so for each field received from the user, I want to use a construction like (age => 'integer').

    And here you should pay attention to special modules that simplify the validation process.

    Modules

    I've found some useful modules on cpan:

    They all have their pros and cons, but none of them met all my criteria.

    Criteria

    1. Control flow the field to the validator, and not vice versa

    This means that the code used fields as first class entities:

    { email => qw(required, email), age => qw(integer, min:18), }

    And not validators:

    { required => qw(email), email => qw(email), integer => qw(age), min => { filed => ‘age’, num => 18 }, }

    2. Required is validator too

    Very often you can see:

    { required => … , validators => { … } }

    Requred is the same validator and it is not clear to me why to extract it into a separate entity.

    3. Has a set of built-in validators

    Not all modules have built-in validators and you need to implement them yourself.

    4. Easily extendable with new modules or custom code

    This feature is provided by most modules.

    5. It has a minimal set of dependencies and does not require the mandatory use of DBIc or Moose

    Because we have a Dancer2 project and maybe we don't use DBIc models at all.

    6. Multilingual support

    Didn't find it anywhere.

    7. Tightly integrated with Dancer2 and provides a set of handy dsl words and html templates tokens

    I do not want to constantly get and transfer data to the template like errors or old input.

    Dancer2::Plugin::FormValidator

    Based on the above criteria, I decided to write my plugin specifically for Dancer2. Since this is my first big OS project, I ask respected monks to share their opinion on what I got as a result.

    use Dancer2; use Dancer2::Plugin::FormValidator; package RegisterForm { use Moo; with 'Dancer2::Plugin::FormValidator::Role::Profile'; sub profile { return { username => [ qw(required alpha_num_ascii length_min:4 + length_max:32) ], email => [ qw(required email length_max:127) ], password => [ qw(required length_max:40) ], password_cnf => [ qw(required same:password) ], confirm => [ qw(required accepted) ], }; } } post '/form' => sub { if (validate profile => RegisterForm->new) { my $valid_hash_ref = validated; save_user_input($valid_hash_ref); redirect '/success_page'; } redirect '/form'; };

    Plugin can be found on Metacpan => Dancer2::Plugin::FormValidator.
    Github repo => dancer2-plugin-formvalidator.

    I am think about the following questions:

    • How convenient is the dsl keywords interface? Is the word validated redundant? Moreover, it uses a global variable. But it looks helpful.
    • How complete is the set of basic validators, is it worth expanding it, with what?
    • In tests, pieces of code are often repeated, is there a generally accepted method of reusing them?
    • Is the documentation clear, what should be added or removed?
    • Are the interfaces friendly to extensions: Extension.pm, Validator.pm
FY411: Missing Perl on package managers for Mac and Windows
1 direct reply — Read more / Contribute
by perlfan
on May 03, 2022 at 14:12
Pangram challenge: greed and Scrabble
2 direct replies — Read more / Contribute
by Athanasius
on Apr 24, 2022 at 10:43

    Task 2 of the current Perl Weekly Challenge is to generate a pangram from the English dictionary provided. “A pangram or holoalphabetic sentence is a sentence using every letter of a given alphabet at least once.”1 However, for this challenge the requirement that the words form a sentence is removed: a list of unrelated words is all that is required.

    The bonus challenge is to “Constrain or optimize for something interesting,” and the first suggestion given is:

    Shortest possible pangram (difficult)

    Ok, so just how difficult would it be to perform an exhaustive search? I don’t know the answer, but since the search space increases exponentially as words are added to the dictionary, a search for sequences (of varying lengths) drawn from a pool of 23,610 words (see below) would appear highly impractical. I haven’t attempted it.

    Before we proceed, it should be noted that the dictionary can be significantly reduced in size before the search begins. Where groups of words share the same set of letters, only one word from the group (the shortest) need be kept. For example, “abdicate,” “diabetic,” and “abdicated” all have the letter set {a, b, c, d, e, i, t}, so “abdicate” is retained but “diabetic” and “abdicated” are filtered out. This reduces the dictionary size from 39,172 to 23,610 — a saving of 15,562 words!

    As noted above, 23,610 is still far too many words for an exhaustive search. So we’re looking for a way to get a close-to-optimum result in a reasonable time. And as we’ve just noted, each dictionary word can be considered as a set of its component letters. So the task is to find a minimum set cover, a well-studied problem in combinatorics and computer science.2 And there is an algorithm that is known to give good results in polynomial time: the greedy algorithm:

    at each stage, choose the set that contains the largest number of uncovered elements.

    My initial implementation of this algorithm produced the following pangram:

    oversimplification ladybug hawk jazz equinox (40 letters)

    I wasn’t satisfied with this, so began looking for ways to improve the search. It occurred to me that words with rare letters should be preferred over words with common letters. This immediately suggested the Scrabble3 points system:

    const my %ALPHABET => ( a => 1, b => 3, c => 3, d => 2, e => 1, f => 4, g => 2, h => 4, i => 1, j => 8, k => 5, l => 1, m => 3, n => 1, o => 1, p => 3, q => 10, r => 1, s => 1, t => 1, u => 1, v => 4, w => 4, x => 8, y => 4, z => 10 );

    With this I was able to give each word a weighting based on its component letters, and prefer words with higher weightings. This produced the following pangram:

    sympathized quarterbacking reflexive jawbone (41 letters)

    — no improvement at all! The problem appears to be that the selected words contain too much deadweight — too many redundant letters. So would it help to adjust the weighting for each word by deducting points for redundant letters? I experimented with different values of $DUP_WEIGHT, the amount to deduct for each redundant letter. Here are the results:

    $DUP_WEIGHT Pangram Letter Count
    1 sympathized quarterbacking jinx overflow 37
    2 sympathized quacking overflow jinx be 33
    3 sympathized quacking fox jaw verb all 32
    4 sympathized unblock xv jaw qt frog 29

    Eureka! At 29 letters, the last pangram is only 3 letters above the theoretical best-possible result of 26. (For values of $DUP_WEIGHT above 4, the result does not change.)

    It should be emphasized that my improved results are not an improvement on the greedy algorithm. That algorithm applies to sets, whereas my search for pangrams is a search over words, which are essentially bags because they contain multiple instances of the same letters.

    For the implementation, I found the Set::Tiny module very useful. I highly recommend it for working with sets of strings.

    Wikipedia1 gives the following as a short pangram:

    Waltz, bad nymph, for quick jigs vex. (28 letters)

    Since all these words occur in the given dictionary, it would be possible for a search to improve on my best solution by at least one letter. Challenge: can anyone implement a search which finds this pangram (or a shorter one) within a reasonable time?

    Full code listings for my solution (in Perl and Raku) will shortly be are available on the Weekly Challenge’s GitHub repository at https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-161/athanasius.

    Cheers,

    1“Pangram, ” Wikipedia, https://en.wikipedia.org/wiki/Pangram
    2“Set cover problem,” Wikipedia, https://en.wikipedia.org/wiki/Set_cover_problem
    3 “Scrabble letter distributions,” Wikipedia, https://en.wikipedia.org/wiki/Scrabble_letter_distributions#English

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Trading compile time for faster runtime?
7 direct replies — Read more / Contribute
by melez
on Apr 20, 2022 at 09:54

    Perl optimizations are pretty basic, and it compiles fast - which is great for utility scripts, but sometimes it feels like a waste of potential. A lot of Perl code actually runs persistently, either behind mod_perl, plack server, mojolicious server or just as a daemon.

    I've been thinking - what if we had a switch (executable flag?) that would turn on additional set of compile time optimizations? It could hypothetically be a big performance win, and not affect programs that need to boot fast. I have close to no experience in XSUB, so that's a big if.

    For example, one of my projects has I think close to 100 .pm files and compiles in 800 ms. It will then run for a long time (in production) and require performance. Other than testing and development, I wouldn't mind spending 10 seconds extra if that would mean some crucial parts would run 50% faster. Or maybe I could care less about using small subroutines in tight loops, as they would get inlined.

    Comments? Was it attempted already?

Critique of some perl code.
3 direct replies — Read more / Contribute
by jwkrahn
on Apr 17, 2022 at 03:03

    Hello Everyone,

    I occasionally like to download perl programs off the web to see how they work. And if there are any bugs I try to report back to the original author.

    This code was found verbatim (except for the file name) in two different files.


    my $conf = which_conf($configuration_file); if (-f $conf) { my @conf_args; open(my $conffile, '<', "$conf") or warn "$P: Can't find a readable $configuration_file file $! +\n";

    It looks like there is a race condition between the file test and the file open.

    The file test does not print a message if the file is not found but the file open does.

    If the file cannot be opened a message is printed and then another message is printed when readline tries to read from an invalid file handle.

    The file name is copied to a string.


    while (<$conffile>) { my $line = $_;

    Data is assigned to $_ and then copied to $line but $_ is never used inside the loop.


    $line =~ s/\s*\n?$//g;

    This is the line that gobsmacked me. I ran some tests with Benchmark and re 'debug' compared to the FAQ answer "s/\s+$//;" and it turns out that this is a good example of what not to do.

    This substitution was found in five places in one file and two places in the other file.


    $line =~ s/^\s*//g;

    Not as bad as the previous line but still not as good as the FAQ answer.


    $line =~ s/\s+/ /g;

    Correct code, nothing to see here.


    next if ($line =~ m/^\s*#/); next if ($line =~ m/^\s*$/);

    Why check for whitespace after you've just removed it?


    my @words = split(" ", $line); foreach my $word (@words) { last if ($word =~ m/^#/); push (@conf_args, $word); }

    This code is where the work is done and obviates the need for the previous five lines. split(" ", $line) removes all whitespace. foreach will not loop if @words is empty. $word =~ m/^#/ will skip to the next line if a '#' comment is found.


    close($conffile);

    Correct code, nothing to see here.


    unshift(@ARGV, @conf_args) if @conf_args;

    The conditional is not really required.


    Where I found this code:

Remembering Sven Guckes - a perl hacker perspective
No replies — Read more | Post response
by cavac
on Apr 15, 2022 at 06:29

    A couple of months ago, my friend Sven Guckes passed away.

    When we met in person, once or twice a year, it was mostly him teaching me new stuff. That's what he always did, with everyone: Showed people new tips and tricks for the command line, helped them out whenever he could without asking anything in return. In February 2021, he asked in Twitter for a way to convert his text-only conference "diary" (a list of events at a conference) to an RSS feed. I whipped up a quick proof of concept. It was not perfect by any means, but he liked it.

    He had a format in his text files like this:

    * 2021-02-15 08:10:00 Working for Twitter now? Sven on Twitter asked to whip up a script to turn diaries into RSS fee +ds. * 2021-02-15 08:20:00 That was easy! All done! This was easier than expected!

    And this is what i came up with.

    #!/usr/bin/env perl use strict; use warnings; use HTTP::Date; use Time::Piece; use Carp; my $gmtoffset = 1; # Hours print '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" +xmlns:atom="http://www.w3.org/2005/Atom">', "\n"; print '<channel>', "\n"; my ($date, $title); my @content; while((my $line = <>)) { chomp $line; if($line =~ /^\*\ (\d\d\d\d\-\d\d\-\d\d\ \d\d\:\d\d\:\d\d)/) { my $temp = $1; if(defined($date)) { printItem(); } $date = $temp;; $title = <>; @content = (); chomp $title; next; } next unless defined($date); push @content, $line; } if(defined($date)) { printItem(); } print '</channel>', "\n"; print '</rss>', "\n"; exit 0; sub printItem { print '<item>', "\n"; print '<title>', $title, '</title>', "\n"; print '<pubDate>', toWebdate($date), '</pubDate>', "\n"; print '<description>', join('<br/>', @content), '</description>', +"\n"; print '</item>', "\n"; return; } sub toWebdate { my ($localdate) = @_; my $webdate; my $unixtime = Time::Piece->strptime($localdate, "%Y-%m-%d %H:%M:% +S")->epoch(); $unixtime -= $gmtoffset * 3600; $webdate = time2str($unixtime); return $webdate; }

    Then you run it with perl diary2rss.pl < testdiary.txt and get:

    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:a +tom="http://www.w3.org/2005/Atom"> <channel> <item> <title>Working for Twitter now?</title> <pubDate>Mon, 15 Feb 2021 07:10:00 GMT</pubDate> <description><br/>Sven on Twitter asked to whip up a script to turn di +aries into RSS feeds.<br/></description> </item> <item> <title>That was easy!</title> <pubDate>Mon, 15 Feb 2021 07:20:00 GMT</pubDate> <description><br/>All done!<br/><br/>This was easier than expected!</d +escription> </item> </channel> </rss>

    We were planning to get together this year, maybe look into writing a proper tool for him to use. But sadly, this will not happen.

    Thank you, Sven, for teaching me so much. I just wish i could have returned the favours.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Module name: PDL::WebSocket?
2 direct replies — Read more / Contribute
by etj
on Apr 06, 2022 at 13:22
    The git-latest PDL (not yet released as 2.078) has, as a new part of its "3d" demo, a 3D model of the Earth (using PDL's OpenGL support), with shading, and shape information. It also has a bug-fixed version of the 3D graph-evolving code added in the late 1990s, which animates the evolution of a molecule-like graph structure, using a form of publish/subscribe.

    Having just looked at https://www.lightningmaps.org/, it uses a websocket to get a live feed of lightning strikes every few seconds, updating a flat Leaflet/OpenStreetMap world map.

    It occurs to me that a module that connected a Mojo::WebSocket to such a live feed, could create a live-updating ndarray to display lightning strikes on our shiny new 3D Earth globe, in a decently eye-catching demo module (using PDL's new plugin-based demo system). What would such a module be called? PDL::WebSocket?

RFC: nicer subs with GetOptionsFromArray from Getopt::Long
2 direct replies — Read more / Contribute
by Discipulus
on Mar 23, 2022 at 08:09
    Hello esteemed folks,

    As few posts running around these days I propose you an idea I had recently and that seems to work as I expected.

    The goal is, as the title says, to use GetOptionsFromArray from Getopt::Long to parse arguments passed to a sub adding the flexibility in arg specification and adding also a primitive type check.

    In the below code the sub test (yeah! what a great name! ;) defines the hash %opts where initial default values are declared and where GetOptionsFromArray will soon put passed in arguments and defines also a @template to hold definitions of various arguments type (with the benefit of a minimal type check for free)

    Here my actual code:

    use strict; use warnings; use Getopt::Long qw(GetOptionsFromArray); use Data::Dumper; my $debug = 0; # 0-2 Getopt::Long::Configure ("debug") if $debug > 1; sub test{ if ($debug){ print "\@_ received: ",Dumper \@_; } # default values in the destination hash my %opts = ( len => 42, switchx => '', # colors => [qw(red yellow green)], # these are NOT ov +erwritten, why? colors => [], ); # copy for debug purpose my %default = %opts; # template for valid options my @template = ( "len|lunghezza=i", "switchx", "tick=i", "colors=s@", ); my $ret = GetOptionsFromArray(\@_, \%opts, @template ) ; # handle errors unless($ret){ print "template for this sub is:\n", "\t",(join "\n\t", @template),"\n", "default values are:\n", ( map{ "\t$_ = ". ( ref ($default{$_}) eq 'ARRAY' ? (join ' ',@{ +$default{$_}}) : $default{$_} ). "\n"}sort keys %default ),"\n"; return; # this should be die } if ($debug){ print "GetOptionsFromArray returned: $ret\n"; } if ($debug){ print "\@_ after GetOptionsFromArray: ", Dumper \ +@_; } print "final \%opts result: ", Dumper \%opts; print "remaining in \@_:", Dumper \@_ if @_; } foreach my $argtest ( [( qw(-len 1111) )], [( qw(-l 11) )], [( qw(-lunghezza 12121212) )], [( qw(-len AAAA) )], [( qw(-len 2222 -un known) )], [( qw(-len 2222 -tick 3333) )], [( qw(-len 2222 -colors blue -colors cyan -colors orange) )], [( qw(-len 2222 --switchx) )], [( qw(-len 3333 --switchx -- Alpha Bravo) )], ){ print "PASSING: (",(join ' ', @$argtest),")\n"; test ( @$argtest ); print "\n"; }

    ..and the output

    I wonder if this behaviour can be put into a module (the original idea was to use Class::Method::Modifiers to inject code just before the original subroutine) but I wonder if it is worth to and notably which interface to expose. Perhaps something like Sub::Getopt::Long is a nice name for this.

    An eventual module interface should be similar to a simple:

    use Sub::Getopt::Long qw( longargs ); sub MyOwnStuff{ my %opts = ( len => 1, wid => 2); # defaults %opts = longargs( \%opts, [qw( len=i wid=i )], @_ ); # or simply my %opts = longargs( {len => 1, wid => 2}, [qw( len=i +wid=i )], @_ ); }

    Any comment or suggestions are as always warmly welcome!

    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.
Combining Function::Parameters with Type::Standard's InstanceOf
1 direct reply — Read more / Contribute
by choroba
on Mar 16, 2022 at 10:33
    When using the Types::Standard's InstanceOf in combination with Function::Parameters, the code using plain InstanceOf doesn't compile:

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { package My; sub new { bless {}, shift } } use Function::Parameters; use Types::Standard qw( InstanceOf ); fun validate(InstanceOf['My'] $m) { # <- Fails :-( say "object:", $m; } my $m = 'My'->new; validate($m);

    The exact error message is

    In fun validate: missing type name after '[' at 1.pl line 13.

    It seems both the modules extend the parser somehow and they step on each other's toes.

    Fortunately, it's pretty easy to fix that: you can prevent Function::Parameters from interpreting the InstanceOf before Types::Standard handles it by enclosing it into parentheses:

    fun validate((InstanceOf['My']) $m) { # <- Works :-) # ~ ~

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Life is steering me into a new direction and lack the time to maintain MCE
3 direct replies — Read more / Contribute
by marioroy
on Feb 18, 2022 at 04:11

    Greetings,

    I can no longer maintain MCE, MCE::Shared, et cetera. It's not an easy decision that's for sure. Over the years I chose PerlMonks to answer questions and provide solutions and what not. PerlMonks has been great.

    I cannot imagine anybody wanting to take over MCE. Rather start new. Either way, I'm not sure the process to transfer MCE and MCE::Shared.

    Regards, Mario

Perl's valentine day
No replies — Read more | Post response
by AlexP
on Feb 14, 2022 at 07:40

    Hi monks! Just wanna share my supper mood. My girlfriend gave me this stylish shirt today:

    It is valuable, when close people know your life. And it is unbelievably cool, that we have such language as Perl. And the best community among all programming languages. Even without using Perl in my work (🥲), I get a huge positive impact on my work and programming skills scrolling through the posts on perlmonks.

    I wanna say thanks to all of you, Larry and Perl! ❤️

Calling an overload::Method
2 direct replies — Read more / Contribute
by hv
on Feb 03, 2022 at 13:43

    You probably won't need to know this, but here it is just in case you do. I stumbled across it while trying to add some speedups to Math-GMP, which uncovered a bug in Test-Builder; a cpangrep then found 5 other distributions trying to do the same thing, all of which also had the same bug (as well as a few that simply bundle Test::Builder).

    If you use overload to make your objects behave specially - as Math::GMP does, to make the objects act more like perl's numeric scalars - you provide those behaviours by way of a hash keyed on the (occasionally cryptic) name of the behaviour, providing a coderef or a function name:

    package My::SuperNumber; use overload ( # overload the subtraction operator '-' => sub { my($self, $other, $swap) = @_; my $result = $self->my_super_subtract($other); return $swap ? -$result : $result; }, );

    That $swap is there to handle asymmetric operations like subtraction: if the caller asks for $super - 12 perl will call that coderef with ($super, 12, 0) as parameters, but if they ask for 34 - $super perl will instead pass ($super, 34, 1) to say that the parameters have been swapped.

    Now for simplicity perl always calls these overload functions the same way, even for unary operators:

    use overload ( # this is the cryptic name of the "numification" operator '0+' => sub { my($self, $other, $swap) = @_; return $self->as_number; }, );

    $other and $swap are still passed in when calling this method (as undef and 0), but of course everyone ignores them and writes the function above as if it took only one parameter. And that's all fine until you want to use XS to provide the overloaded method - at the C level you can't just ignore arguments you don't care about, you have to supply a signature that matches how it is called. So you have to write something like this:

    use overload ( # this is the cryptic name of the "stringification" operator '""' => op_stringify, ); # and then in the XS code: char * op_stringify(left, right, swap) SV * left SV * right bool swap CODE: RETVAL = my_stringify(left); OUTPUT: RETVAL

    .. and that's all fine too - XS writers expect to have to do things in slightly more convoluted ways. However, back in the land of Perl, the overload module also provides a Method function which allows you to ask for the coderef that _would_ be called for a particular overloaded operation. You might use that to check if it's safe to use something as a string, for example:

    sub as_string { my($obj) = @_; return "$obj" unless ref $obj; die "Give me a string, or something that pretends to be one" unless overload::Method($obj, '""'); return "$obj"; }

    However you might also use it to invoke that method yourself, and this is the thing that everyone got wrong:

    sub as_string { my($obj) = @_; return "$obj" unless ref $obj; my $method = overload::Method($obj, '""') or die "Give me a string, or something that pretends to be one"; # WRONG return $method->($obj); # RIGHT return $method->($obj, undef, 0); }

    If you invoke the coderef returned by overload::Method without supplying 3 arguments, that may work fine as long as you only interact with objects whose overloads are provided by perl code, but trying to invoke an XS method that way will fall over at runtime with a message like Usage: My::SuperNumber::as_string(left, right, swap) - because they _had_ to write it with that signature to let perl call it. And since use of XS is fairly rare and use of overload is even more so, it may be a long time before you discover there's a bug. So don't do that. :)

Leap years? How does that work?
3 direct replies — Read more / Contribute
by talexb
on Feb 01, 2022 at 21:33

    In my defence, I'm a nerd. Dad's a retired actuary, and I've been fiddling with math and logic puzzles forever. So it made sense that an idea that's been bubbling away in my head decided to wake me this morning. I wanted to write it down immediately, but I had to have breakfast, then I had to head out for my weekly grocery shopping during a pandemic thing, then I had to put in my work day. Then I had supper and a couple of glasses of wine.

    So at this point, I'm ready to jot down a few thoughts on leap years.

    Imagine, if you will, the time and effort it took for people to realize that while 365 days in a year was very close, it was not quite the right value. Then imagine the you are the brave astronomer and local science dude who has to have a polite conversation with, say, The Pope about this, having already braved the underlings and the Pope's secretary. Why the Pope? Because he's the one who is going to say, OK, we're going to change the calendar now., and people are going to listen and obey.

      Astronomer: You Holiness, Thank you for taking time out of your day to see me. I will be brief.

      The Pope: Galileo! So good to see you. Please, call me Jules!

      A: Your Holiness, please.

      TP: OK, OK, I kid. So, they tell me you want to change the calendar? How's that work?

      A: OK, You may recall we have been using 365 days in a year, but you will also know that we've discovered this is incorrect -- we're falling behind. The Winter solstice is now mid-January, and we need to sort things out.

      TP: Yes, yes, that's fine, we'll just publish a decree to reset the date. Will that be all?

      A (quaking a little): You holiness, it's a bit more complicated. We need to add an occasional day to make things work out. A year is about 365.24 days.

      TP: Ah, so your first approximation is to add a day every four years?

      A (surprised): Your Holiness! You have an excellent grasp of the mathematics!

      TP: Yes, yes, thank you. But this gets us only part the way there. What else?

      A: Well, every hundred years we'll skip the extra day.

      TP: Is that it?

      A: Also, every four hundred years, we have to add it back in.

      TP: Well, that sounds fine. So we'll an extra day in December, and make it 32 days every .. once in a while?

      A: Well, your holiness, that is a possibility, but I'd like to suggest making the shortest month the recipient of this extra day. Say, February, which currently has just 28 days.

      TP: An extra day of winter? Are you sure that's wise?

      A: As you know, holiness, winter is 91 days, no matter when they fall.

      TP: Very well, very well. So, February 29th every now and then?

      A: Yes, that's all.

    Anyway, this is a Perl site, so the obligatory code snippet is

    sub is_leap_year { my $year = shift; # We assume that validation has taken place. if ( $year % 400 == 0 ) { return 1; } elsif ( $year % 100 == 0 ) { return 0; } elsif ( $year % 4 == 0 ) { return 1; } else { return 0; } }
    And I pray to the FSM that this code's right.

    And .. someone below will no doubt chime in about the details of the Julian calendar .. you're quite right, I did absolutely no research on this (apart from my likely faulty memory), but I just thought it would have been an entertaining discussion about Changing The Calendar .. although that far back, it probably had far less impact on most people living their lives.

      Peasant #1: Oy! What day is it?

      Peasant #2: Haven't the faintest. Epiphany was a few days ago, so late January, early February is my guess. Why do you care?

      P1: Good point. Just curious .. I heard they were changing the calendar.

      P2: Madness. Change the calendar? Why?

    Edit: Yeah, I got the code wrong. Fixed it already. ugh

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

PerlMonks - my haven of calmness and sanity
5 direct replies — Read more / Contribute
by cavac
on Jan 27, 2022 at 08:20

    It has taken me a long time to talk about this in public, but i think it's finally time to tell you: I am on the autistic spectrum.

    A lot has been written about the subject, so i wont bore you with too much detail. Autism is a sliding scale, with many a variation on how this can affect an individual.

    For me, i have trouble keeping a conversation going both ways (i tend to talk non-stop if i get any chance). For some strange reason, this is much easier in writing than it is in person. When i write (and read), i usually can take my time, and analyze what the other people are saying and slowly formulate my answers. In person, i can still do it (depending on the subject), but it is very stressful. I also have trouble understanding non-verbal cues, can't remember faces very well and stuff. To others, I also tend to have a very dark humor; for everything else i tend to apply logic. But mostly, for me it's a day-to-day struggle to appear somewhat normal in public and somehow muddle through the day without completely loosing my mind or doing something incredibly stupid. There are other things as well, but these are for another time, perhaps. But basically, think "high-functioning autism", i can hide my traits by many learned ways of coping with stuff, but this requires a lot of active concentration and it's quite stressful and exhausting to do (if you ever meet me in person, you'll probably notice my various social "skills" dropping fast whenever i am tired).

    The reason why i'm writing this is simple: PerlMonks has been a haven of calmness and sanity to me over many, many years. It gives me a chance to learn from and give back to others. Sometimes, i only lurk here without writing for months, then there are times when i'm ready to take on quest after quest to try and help out in SoPW. The discussions here are generally held in a calm and logical fashion that let me participate in my own way and at my own speed. And for this, i am eternally grateful to all of you.

    Thank you from the bottom of my heart!

    Edit: Ask me questions. I'll answer them if i can.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'

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":


  • 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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2022-05-23 15:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (82 votes). Check out past polls.

    Notices?