Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
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
Reinventing Moops
No replies — Read more | Post response
by tobyink
on Jan 14, 2020 at 05:20

    It seems every few years, I come up with some kind of weird syntax extension for doing OO programming in Perl. Moops was the most recent but while it's cool, it's built on some shaky foundations.

    I've been working on this thing MooX::Press for a little while now. It allows you to define a bunch of classes in one use statement. Like:

    use MooX::Press ( prefix => 'MyApp', role => [ 'Livestock', 'Pet', 'Milkable' => { can => [ 'milk' => sub { print "giving milk\n"; }, ], }, ], class => [ 'Animal' => { has => [ 'name' => { type => 'Str' }, 'colour', 'age' => { type => 'Num' }, 'status' => { enum => ['alive', 'dead'], default => 'alive' }, ], subclass => [ 'Panda', 'Cat' => { with => ['Pet'] }, 'Dog' => { with => ['Pet'] }, 'Cow' => { with => ['Livestock', 'Milkable'] }, 'Pig' => { with => ['Livestock'] }, ], }, ], ); my $porky = MyApp->new_pig(name => 'Porky'); print $porky->status, "\n";

    It's designed to be as declarative as possible; with the exception of a coderefs for defining your methods, it's pretty much just a big hash that could be serialized as JSON or YAML or whatever. Indeed, I've written portable::loader as a way of loading MooX::Press classes/roles from JSON or TOML and deciding their package namespace at runtime.

    It's also very opinionated about how your classes and roles should be interacted with. Although MyApp::Pig->new works, you are encouraged to use MyApp->new_pig instead. And if a Panda object needs to create a Pig (because that happens in nature, right?) then it should call $self->FACTORY->new_pig to do the business. MyApp is the factory package, and objects get created via that; objects can find their factory package using $self->FACTORY. There are ways to override some of MooX::Press's opinions, but it steers you in this direction.

    Anyway, recently I started looking at how to combine this with Keyword::Declare to create something Moops-like. This is the syntax I have currently got working:

    use v5.14; use strict; use warnings; use Data::Dumper; use MooX::Press::Declare prefix => 'MyApp', toolkit => 'Moo'; class Quux { version 3.1; extends Quuux; with Xyzzy; has foo : ( is => ro, type => 'Foo' ); has bar : ( type => 'Barrr' ); has nooo!; # exclamation mark means required constant yeah = 42; method say_stuff { my $self = shift; say $self->yeah + $self->nooo; } } my $obj = MyApp->new_quux( foo => MyApp->new_foo, bar => MyApp->new_bar_baz, nooo => 1, ); print Dumper($obj); $obj->say_stuff; # Note the order you define stuff mostly doesn't matter. # We used these classes above and define them now. class Quuux; role Xyzzy; class Foo; class Bar::Baz { type_name Barrr; }

    It's still early days, but it's coming along pretty nicely too. I'm impressed with how easy Keyword::Declare makes syntax extensions.

    Still to do: method signatures, method modifiers (before, around, after), type coercions, and custom factory methods. (These are all supported by MooX::Press, but not by the declarative syntax yet.)

Mini-Tutorial: Formats for Packing and Unpacking Numbers
1 direct reply — Read more / Contribute
by ikegami
on Jan 06, 2020 at 03:49

    pack and unpack are useful tools for generating strings of bytes for interchange and extracting values from such strings respectively. What follows is a table that represents the relevant formats in a convenient form.

    Category Type Byte Order Mnemonic
    Native Little-Endian (<) Big-Endian (>)
    Fixed-Size
    Integers
    8-bit
    integer
    Unsigned C "C" for char
    Signed c
    16-bit
    integer
    Unsigned S S< or v S> or n "S" for short
    Signed s s< or v! s> or n!
    32-bit
    integer
    Unsigned L L< or V L> or N "L" for long
    Signed l l< or V! l> or N!
    64-bit
    integer
    Unsigned Q Q< Q> "Q" for quad
    Signed q q< q>
     
    Types Used
    By This Build
    of perl
    UV (unsigned integer) J J< J> "J" is related to "I"
    IV (signed integer) j j< j>
    NV (floating-point) F F< F> "F" for float
     
    Underlying
    C Types for
    This Build
    of perl
    unsigned short int S! S!< S!> "S" for short
    signed short int s! s!< s!>
    unsigned int I! or I I!< or I< I!> or I> "I" for int
    signed int i! or i i!< or i< i!> or i>
    unsigned long int L! L!< L!> "L" for long
    signed long int l! l!< l!>
    float f f< f> "f" for float
    double d d< d> "d" for double
    long double D D< D> A bigger double

    Notes:

    • < and > indicate byte order. The small end of the bracket is at the least significant end of the number. (< for little-endian byte order, and > for big-endian byte order.) Can't be used with N/n and V/v.
    • For integers, ! signifies using the C types of this build of perl. N/n and V/v excepted.
    • For integers, uppercase indicates unsigned, and lowercase indicates signed. N/n and V/v excepted.
    • N and n are used for network (i.e. internet) byte order (BE), with the uppercase letter being used for the larger bitsize.
    • V and v are used for VAX byte order (LE), with the uppercase letter being used for the larger bitsize.
"exists $hash{key}" is slower than "$hash{key}"
3 direct replies — Read more / Contribute
by swl
on Jan 05, 2020 at 19:23

    UPDATE 2020-01-10: Actually, it's not. See subthread starting at 11111117.

    ----

    I decided to run some benchmarking on hash exists after some code profiling showed a reasonable amount of time spent on lines with next if exists $hash{$key}.

    This is largely in the context of code structured like the (very contrived) example below which uses the common idiom of skipping slow code if it has already been done or is not needed based on a tracking hash.

    my %done; my @data = (1..100); for (1..100) { push @data, int (rand() * 100); } for my $item (@data) { next if exists $done{$item}; # do something time consuming # ... $done{$item}++; }

    The code below tries combinations of exists and value checking. Assignment to variables is used to avoid "Useless use of hash element in void context" warnings, and the assignment to globals is to get a sense of how much the timings are related to bookkeeping of lexicals. I could disable warnings but it's the relative timing differences that are useful here, not the absolute times.

    Code was run using Strawberry perl 5.28.0, and the results are given in the table below (see code for key explanation).

    The main take home is that the value checks (v prefix) are all faster than the exists checks (e prefix). Assigning to global is faster, presumably because there is less bookkeeping involved, but it will be rare that one would use such a construct anyway.

    Rate evksvl evkrvl ecksvl eckrvl evksvg evkrvg vvksvl vvk +rvl vckrvl vcksvl vvksvg vvkrvg evksvl 10733145/s -- -5% -7% -12% -15% -18% -29% - +31% -32% -33% -41% -48% evkrvl 11290643/s 5% -- -2% -7% -10% -14% -25% - +27% -28% -29% -38% -45% ecksvl 11570664/s 8% 2% -- -5% -8% -12% -23% - +25% -27% -27% -36% -44% eckrvl 12176232/s 13% 8% 5% -- -3% -8% -19% - +21% -23% -23% -33% -41% evksvg 12572221/s 17% 11% 9% 3% -- -5% -17% - +19% -20% -21% -31% -39% evkrvg 13168623/s 23% 17% 14% 8% 5% -- -13% - +15% -17% -17% -28% -36% vvksvl 15082826/s 41% 34% 30% 24% 20% 15% -- +-2% -4% -5% -17% -27% vvkrvl 15461840/s 44% 37% 34% 27% 23% 17% 3% + -- -2% -3% -15% -25% vckrvl 15777625/s 47% 40% 36% 30% 25% 20% 5% + 2% -- -1% -13% -23% vcksvl 15909705/s 48% 41% 38% 31% 27% 21% 5% + 3% 1% -- -13% -23% vvksvg 18207860/s 70% 61% 57% 50% 45% 38% 21% +18% 15% 14% -- -12% vvkrvg 20580512/s 92% 82% 78% 69% 64% 56% 36% +33% 30% 29% 13% --

    So why is it that exists is slower than checking the value? My starting assumption was that exists should be faster, as getting a value requires checking that it exists first. However, looking that the source code, most of the hash key and value calls are passed through the same function, hv_common. So far as I can tell from reading the code, and based on my limited comprehension of the details, hv_common prioritises getting values over checking key existence and value assignment.

    So does this all matter and should code that uses exists $hash{$key} be changed to use $hash{$key}? Given that even the slowest of the benchmark snippets is running more than 10,000,000 per second, it does not matter at all for most use cases. One would need to be running hundreds of millions of calls for such a change to start to make a meaningful difference, and some would quite reasonably argue that billions of calls are needed.

    Maybe the perl source code could be optimised so exists is not slower, but whether this justifies any additional maintenance burden is not something I can answer.

Old Programmer New To Perl
13 direct replies — Read more / Contribute
by storm5510
on Jan 01, 2020 at 07:46

    Greetings! I am new to Perl. However, I have been a part-time programmer since 1988. I got my start at the local community college. I am retired and 64 years old.

    I was told by some folks at mersenneforum.org that membership here can be tough. I much prefer to do my own research. Asking questions, like here, is a last resort. I have found that reading others posts can often reveal a solution to what I need.

    As for Perl itself, I am using Strawberry on Windows 10 Pro x64 v1903. I can follow code as long as it is not really complex. This is all I have, for now.

    Have a pleasant New Year's Day.

How to Bisect Perl
No replies — Read more | Post response
by haukex
on Dec 27, 2019 at 14:42

    In several of my nodes, I've used bisection to figure out when certain bugs/features were fixed/introduced. I find this useful because it'll often uncover the discussion that went into a feature or the detailed reasons behind a bug. I thought I'd write about this process, since I don't always document how I ran each bisect.

    First, what is bisection? Basically, it's a (partly automated) binary search to find the exact commit where some behavior changed.

    A simplified example: Say you want to find out which Perl release s///r was introduced. So, you run perl -e 's///r' on the oldest Perl you've got, say 5.6, and on the newest, 5.30 - the former dies, the latter runs, confirming the change happened somewhere between those releases. So then you divide the search space into two, and run the same test on 5.18 - it works, so you now know the change must have happened between 5.6 and 5.18, and you don't need to test the other half of the search space. Divide the search space again, and run the test on 5.12 - it fails, so you know the change must have happened between 5.12 and 5.18. Repeat the process again, and eventually you'll find out that Perl 5.12 dies, but 5.14 works - so you've now confirmed that s///r was introduced in release 5.14, and you didn't have to test all 13 Perl releases from 5.6 to 5.30! (Technically, the change happened in a development version between those two releases, but for this example we've only looked at non-development releases as a stand-in for commits.)

    A real bisect is different from this example in that it works on the granularity of git commits, and it's mostly automated - the Perl source code includes scripts to assist you in running a git-bisect. And instead of using pre-built Perls, the bisection process will check out each commit of Perl and build it from scratch (even applying patches as needed to get older versions of Perl to compile). It can take half an hour to several hours to run a bisect, but once you set it running, you can go and do something else in the meantime.

Printing large numbers with commas to show thousands groups.
3 direct replies — Read more / Contribute
by jnorden
on Dec 26, 2019 at 20:13
    Here is yet another answer to this ancient and oft-asked question (for linux at least).

    The standard advice is found in perlfaq5, on perlmonks, and elsewhere. Using Number::Format or a commify() sub works well, but isn't very convenient for modifying existing code that was written with printf. It seems unlikely that perl's printf will ever support %'d and friends (see printf(3), scroll to "Flag Characters").

    However, almost any linux system has a /usr/bin/printf command with %' support. So, the simple definition

    sub cprintf {system('/usr/bin/printf', @_)}
    will let you use
    cprintf("There are at least %'d ways to do it!\n", 42e6)
    to print: There are at least 42,000,000 ways to do it!

    For this to work, your LC_NUMERIC environment variable should be set to a locale that has a "thousands separator", such as en_US.UTF-8. It seems to work quite well, at least for simple cases. To modify existing code, just change your printf's to cprintf's and add apostrophe's to the formats as needed. Less work than wrapping each argument with a subroutine call and changing each format to %s. It also helps keep things clear and readable.

    It's tempting to override the builtin printf, but that's not easy to do. The CORE documentation lists printf as a special keyword. (Playing with tied file-handles or other tricks might work, but doesn't seem worth it too me.)

    On the other hand, if you want to auto-magically commify *all* your %d's, you could use:

    sub cprintf { my($fmt)= shift; $fmt=~s/%(-?\d*)d/%'$1d/g; system('/usr/bin/printf', $fmt, @_) }
    And then  cprintf("%d", 42e6) will print 42,000,000.


    Happy Holidays, and best wishes for the new year!
    -Jeff

Defining, Testing and Documenting Perl?
2 direct replies — Read more / Contribute
by LanX
on Dec 23, 2019 at 12:03
    Hi

    I started to write a test script for "Boolean Operators" with and w/o "Short-Circuit" in Perl.

    And quickly found me needing to define and test "Truthiness" in Perl.

    (Wait ... "0 but true" is false? Remembered it differently ;-)

    And now I find myself obliged to also define "Contexts", because an empty list is also false.

    And "Data Types", because internally it's more difficult, than just Scalar, Array and Hash.

    It's a lot of work, but in the end it could help in many corners when done correctly:

    • Regression testing between Perl versions
    • Leading to a proper language definition
    • Bottom up documenting the language in POD
    • Helping to test cross implementations in other languages like in JS
    Properly done means that it needs to be axiomatic, i.e. higher level tests need to only use features proven in lower levels.

    Like so often, after a first success I find myself a bit stuck in the big picture.

    I'll throw in my first approach as is for meditation.

    There is a lot to be criticized, but my normal perfectionism is too risky and might lead to a never release cycle.

    Thoughts?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Perl hosting is hard to find
8 direct replies — Read more / Contribute
by harangzsolt33
on Dec 20, 2019 at 10:09
    I was searching for the cheapest Perl hosting online that also allows me to have 10 websites pointing to it. But I am finding out that cheapest is not necessarily good. Maybe I am wrong. But this is the third time I do business with a hosting company that promises to offer perl support and doesn't live up to its claims.

    I'm talking about Netfirms, 50webs, and 1dollar-webhosting.com. These are the three I have tried and paid for. They promised I would get perl scripting, and it wasn't included. I was told to buy the next level up. But if I have to upgrade, then why did they include perl in their special offer or advertising!? Anyway, I didn't get what I paid for, and I was disappointed. Is it common to see hosting companies that say they offer perl and then not deliver on their promise? I mean that's the only reason I chose these hosts, because they included perl in the list.

Dataflow programming on CPU and GPU using AI::MXNet
1 direct reply — Read more / Contribute
by bliako
on Dec 18, 2019 at 07:04

    Computational pipelines, often called Dataflows, are just Graphs describing the interaction of Data with Operators and other Data to produce more Data.

    a*b + c*d is a Dataflow.

    And so is a (feed forward) Neural Network: read input, distribute input matrix to first layer, pass it through activations, sum outputs and distribute to second layer and so on until the output layer. Deep Neural Networks are so complex, deep and convoluted that they thought dataflow programming (which is not new as a field) will aid their training and use. And so TensorFlow and MXNet and others were created.

    The really unfortunate thing is that most of these frameworks are investing heavily on Python interfaces even if internally they use C/C++ for obvious reasons :) . The fact that Python is a TIOOWTDI regime will lead this field to serious cargo-culting (e.g. "In a sparse network, it’s more likely that neurons are actually processing meaningful aspects of the problem." which I have seen before when working with Neural Networks, mid-90's), script-kidding practices and eventual stagnation. Of course the field will recover. And faster and sooner, if and when Python is replaced or other high-level-er (script) languages are equally supported. Nothing stops the machine taking over ...

    In Perl, there is an excellent set of modules written by Sergey Kolychev under AI::MXNet based on Apache's MXNet. Note that it is active and very recently updated: Feb 23, 2019 !!! That's a good sign.

    My cpu and I have spent a lot of cycles trying to install the pre-requisite libraries of Apache's MXNet written in C/C++ and offering also CUDA capabilities. Two hints: do not use github repo version and use Makefile (instead of that cmake).

    Now that I have it all installed (MXNet libraries, Perl module and also R package - unrelated to this post) I would like to share with you all just what size of doors this package opens by introducing a basic dataflow operating on scalars and matrices both on CPU and GPU! The very fact that this package offers, on the side, GPU capabilities within Perl makes it, in my opinion, very very promising. I can't see much offering GPU at CPAN at the moment and here we have one package which opens both GPU and Deep Learning worlds to Perl hackers. (I have no affiliation with S.Kolychev whatsoever)

    So, here is some code to get you started on implementing a pipeline to calculate e=a*b+c*d. At first these AI::MXNet::Symbol (e.g. a,b,c,d,e) will be scalars represented as 1-dimensional AI::MXNet::NDArray (which is somewhat similar to PDL's arrays):

    use strict; use warnings; use AI::MXNet qw(mx); # specify which context we want this dataflow to be executed in # for CPU use mx->cpu(0); (note, (0) does not mean cpuid or something, + it is not used) # for GPU use mx->gpu(0); (0 denotes gpu device id) my $ctx = mx->cpu(0); # create 1D arrays with values: 1, 2, 3, 4 for a b c d respectively # these are DATA my $a_data = mx->nd->array([1], ctx => $ctx); my $b_data = mx->nd->array([2], ctx => $ctx); my $c_data = mx->nd->array([3], ctx => $ctx); my $d_data = mx->nd->array([4], ctx => $ctx); # these are SYMBOLS my $a = mx->symbol->Variable('A'); my $b = mx->symbol->Variable('B'); my $c = mx->symbol->Variable('C'); my $d = mx->symbol->Variable('D'); # these is the EXPRESSION to evaluate # basically our dataflow graph (but still no data on it, just descript +ion) my $e = ($a*$b) + ($c*$d); print "e=".$e."\n"; # this is how we associate data with symbols and specify # whether we want to run this on CPU or GPU my $exe = $e->bind( ctx => $ctx, # this is how we bind data to symbols so our dataflow graph ca +n be "executed" # and a result comes out # Note: create the arrays on the same device as executing them +, i.e. context, ctx, # must be the same here and above in creating the arrays. args => {'A'=>$a_data, 'B'=>$b_data, 'C'=>$c_data, 'D'=>$d_data} ); # propage inputs to the output(s) $exe->forward(1); # we need the first (and only one at this case) output as PDL array print "output: ".$exe->outputs->[0]->aspdl."\n";

    And this is the result:

    output: [14]

    Now, let's replace 1-dimensional data with 2x2 arrays! Just create your data as thus:

    # 2d array data, initialised to these rows (edit: updated to specify c +tx too) my $a_data = mx->nd->array([[1,2],[3,4]], ctx => $ctx); my $b_data = mx->nd->array([[5,6],[7,8]], ctx => $ctx); my $c_data = mx->nd->array([[9,10],[11,12]], ctx => $ctx); my $d_data = mx->nd->array([[13,14],[15,16]], ctx => $ctx);

    But, wait because the * operator on matrices denotes element-to-element multiplication and not the actual matrix multiplication. For that we use:

    my $e = $a->dot($b) + $c->dot($d);

    And the result is:

    [ [286 308] [366 396] ]

    If not evaluating ginormous matrix expressions using a Dataflow framework (which will also parallelise when parallelisation is possible) was not enough we have here another huge door opening for you number crunchers and Perl hackers: the ability to do this using the GPU via CUDA! Just replace the context above with the GPU-related code. And there is light! In this way, CUDA can be used via Perl not only for doing neural network stuff but for any kind of computation which you can express in a Dataflow. For example, load two images as AI::MXNet::NDArray and multiply them on the GPU! Or do some signal processing by loading an mp3 voice file as NDArray! (this paragraph was a 5' later addition)

    One thing that does not add up is that AI::MXNet::NDArray says: "However, NDArray is row-major, unlike the PDL that is column-major.". But PDL is row-major too! So have that in mind.

    Sources+more reading:

    If that does not keep you excited over the Festivus, I don't know what will ...

    Thank you Sergey Kolychev ++

    bw, bliako

    ps. some last 5 min additions and cosmetic changes. Also note the comments in the code provided for more information.

Hacker News! Just another reinvented wheel: uni
2 direct replies — Read more / Contribute
by Anonymous Monk
on Dec 13, 2019 at 23:49
    Four years and seven weeks ago our friend Ricardo SIGNES brought forth on this network, a new program, conceived by Audrey Tang: App::Uni! For some reason a year old clone of uni, written in Go, was advertised as "Hacker News" yesterday:
    Uni: Query the Unicode database from the CLI...
    https://news.ycombinator.com/item?id=21777025
    
    Usage of App::Uni:

    Identify a character:

    uni €
    € - U+020AC - EURO SIGN
    
    Or a string:
    uni -c h€ý
    h - U+00068 - LATIN SMALL LETTER H
    € - U+020AC - EURO SIGN
    ý - U+000FD - LATIN SMALL LETTER Y WITH ACUTE
    
    Search description:
    uni /euro/
    ₠ - U+020A0 - EURO-CURRENCY SIGN
    € - U+020AC - EURO SIGN
    𐡷 - U+10877 - PALMYRENE LEFT-POINTING FLEURON
    𐡸 - U+10878 - PALMYRENE RIGHT-POINTING FLEURON
    𐫱 - U+10AF1 - MANICHAEAN PUNCTUATION FLEURON
    🌍 - U+1F30D - EARTH GLOBE EUROPE-AFRICA
    🏤 - U+1F3E4 - EUROPEAN POST OFFICE
    🏰 - U+1F3F0 - EUROPEAN CASTLE
    💶 - U+1F4B6 - BANKNOTE WITH EURO SIGN
    
    Multiple words are matched individually:
    uni globe earth
    🌍 - U+1F30D - EARTH GLOBE EUROPE-AFRICA
    🌎 - U+1F30E - EARTH GLOBE AMERICAS
    🌏 - U+1F30F - EARTH GLOBE ASIA-AUSTRALIA
    
    Print specific codepoints or groups of codepoints:
    uni -u 2042
    ⁂ - U+02042 - ASTERISM
    
    uni -u 2042 2043 2044
    ⁂ - U+02042 - ASTERISM
    ⁃ - U+02043 - HYPHEN BULLET
    ⁄ - U+02044 - FRACTION SLASH
    
    AFAIK App::Uni does not have the -race (I mean -tone) or -gender switches of the Go uni so there was some innovation I guess.

    Anyway my meditation consists of encouraging Perl programmers to announce their wares on Hacker News, and other such websites.

    https://news.ycombinator.com/news
    
Beware of global! And bless the local!
3 direct replies — Read more / Contribute
by alexander_lunev
on Dec 12, 2019 at 03:40

    Hello monks.

    Today I found that a little negligence can cause a week-long debugging.

    I wrote a program that uses Crypt::OpenPGP module, and for a strange reason module works great when I simply initialize it with keyrings from file, but it crashes when i first read keyrings from files and combines them for my needs and then initialize module with constructed keyring objects. Terrible crashes of the Perl interpreter itself (sic!) was accompanied by cryptic messages like these:

    Win32::API::parse_prototype: WARNING unknown parameter type 'PVOID' at + C:/Strawberry32/perl/vendor/lib/Win32/API.pm line 568. Win32::API::parse_prototype: WARNING unknown parameter type 'ULONG' at + C:/Strawberry32/perl/vendor/lib/Win32/API.pm line 568. Win32::API::parse_prototype: WARNING unknown output parameter type 'IN +T' at C:/Strawberry32/perl/vendor/lib/Win32/API.pm line 600. Argument "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0..." + isn't numeric in subroutine entry at C:/Strawberry32/perl/vendor/lib +/Crypt/Random/Seed.pm line 247.

    I was wondering - what have i done to bring this punishment upon me? I compared objects that come out from keyring-file initialization and from keyring-objects initializations with Data::Dumper and couldn't find a difference. I even saved constructed keyring objects to files and initialize Crypt::OpenPGP with this newly created files - still all was crashing. The holy fear seized me and I decided to start my journey to the depth of module forest to find deliverance. I walk through Crypt::OpenPGP to Bytes::Random::Secure, to know that road leads - as it was told to me in the cryptic omen - to Crypt::Random::Seed, line 247, which was a Call to Win32::API function:

    my $rtlgenrand = Win32::API->new( 'advapi32', <<'_RTLGENRANDOM_PROTO_' +); INT SystemFunction036( PVOID RandomBuffer, ULONG RandomBufferLength ) _RTLGENRANDOM_PROTO_ return unless defined $rtlgenrand; return ('RtlGenRand', sub { my $nbytes = shift; my $buffer = chr(0) x $nbytes; my $result = $rtlgenrand->Call($buffer, $nbytes); # <= 247

    My journey comes to a dead end, for I didn't find deliverance there. And I started from the beginning of my code, turning lines of code off one by one. And I found it.

    This is the code that was a root of all misfortunes.

    open my $fh, "<", $file or die "can't open $file"; $/ = undef; my $key_string = <$fh>; close $fh;

    If you're enlightened enough, you will see my sin right away. I'm not enlightened enough to see it right away, but a doubt crawls into my mind - could it be the line $/ = undef;? I stared at this line for a minute and go search wisdom on the Internet. And then I found the Truth. And as always the Truth was under my nose all the time, but I couldn't see it. It should be local $/ = undef;!

    I don't know if it is clean and right way to read all file in a string, but even the great Gabor Szabo blesses slurp mode by setting $/ = undef;. But beware if you read his great article not thoroughly! The great misfortune awaits those who forget about local in a rush! Like me for example.

    You see? Setting $/ = undef; globally make things broken all the way up to the Perl interpreter itself, which was casting strange messages on his way to crash.

    But why would anyone write about it again, and again, and again? Because, as it said in every language:

    Repetitio mater studiorum est.

    Repetition is the mother of all learning.

    Wiederholen ist die Mutter des Studierens.

    La répétition est la mčre de la science.

    Повторение - мать учения.

    Let my mistake will be a lesson to others. Using global variables is always a risky and erroneous path, local variables is the only way to enlightenment. But this is the Truth that we were told from the beginning and we are still making this silly mistakes. And while we code simple programs, errors are simple and debuggable. But when we become more mature - so are the errors that we cause by violation of a simple rules that we doesn't learned well from the start. Beware of global! And bless the local! Amen.

RFC: "assignary" operator ?= :
7 direct replies — Read more / Contribute
by richard.sharpe
on Dec 07, 2019 at 11:01

    Hello guys,

    I would like having new type of assignment operator in perl, the combination of assignment and ternary operator (therefore calling it "assignary"):

    ?= :

    Not in context of regular expressions, not related with (?=) in any way, but in regular assignment. I haven't found something like that in perlop.

    Suggested meaning:

    $var ?= "something" : "something else";

    would be equivalent to:

    $var = $var ? "something" : "something else";

    Advantage of the first: more compact, as not writing $var two times.

    What do you think about possible existence of such hybrid of ternary and assignment operators?

Jumbo Signatures extensions discussion
2 direct replies — Read more / Contribute
by Corion
on Nov 29, 2019 at 02:14

    dave_the_m has posted a long and very comprehensive thread to perl5-porters in which he outlines his plans for subroutine signatures. The plan is to get a consensus on the syntax of the various features and then to implement them over the next year. The goal is to have subroutine signatures out of experimental status by Perl 5.36. Whatever breaking of backwards compatibility with the existing (experimental) subroutines is necessary should go into 5.32.

    I have mostly copied the Synopsis section of each mail here, and I really encourage you to look at the mails themselves which contain far more discussion of the proposed behaviours.

    The separate threads are:

    Jumbo Signatures extensions discussion - the top level thread

    Here is a contrived example of a signature which demonstrates many of the proposals. Some of it will make more sense after each proposal has been read.

    sub foo ( $self, # parameter declarations starting with '?' examine, # but don't consume any further arguments: ?*@args, # @args is set to the equivalent of @_ with one # arg shifted; i.e. like a slurpy but peeking ahead # and not actually consuming any args; the '*' means # that each @args element is aliased to a passed arg ?$peek_a, # $peek_a is bound to next arg but without consuming + it ??$has_a, # $has_a is set to true if there's an argument for $ +a $a, # normal scalar parameter ?{ print $a },# embedded code block - runs code; doesn't shift arg +s Dog $spot, # works the same as 'my Dog $spot' $b :shared, # you can use normal variable attributes $c :ro, # at compile time, $c in lvalue context croaks \@ary, # aliases @ary to a passed array reference \%hash, # aliases %hash to a passed hash reference *$scalar, # aliases $scalar to the next argument # Constraints and coercions: $d!, # croak if $d not defined $e isa Foo::Bar, # croak if $e isn't of that class $f is Int where $_ > 0, # croak if $f not a positive integer $x = 0, # a default value $y?, # short for $y = undef \@array?, # short for \@array = [] :$name1 = 0, :$name2 = 0, # consume name-value pairs (name1 => ..., name2 => . +...) @rest # slurp up any remaining arguments ) { .... }

    Parameter Attributes

    sub f ($x :foo, $y :bar(baz) bar2(baz2), ...) { ... }

    analogous to:

    my $x :foo; my $y :bar(baz) bar2(baz2);

    Perl should support parameter attributes.

    What exactly should the semantics be? Lets first review the current syntax as applied to 'my' declarations:

    my ($x, $y) :foo(foo_arg) :bar(bar_arg);

    is roughly equivalent to

    use attributes (); my ($x,$y); attributes->import(, __PACKAGE__, \$x, "foo(foo_arg)", "bar(bar_ar +g)"); attributes->import(, __PACKAGE__, \$y, "foo(foo_arg)", "bar(bar_ar +g)");

    Named Parameters

    sub foo ( $pos1, # positional parameter; consumes 1 arg $pos2, # positional parameter; consumes 1 arg :$name1, # named parameter, consumes ("name1", value) arg +pair :$name2, # named parameter, consumes ("name2", value) arg +pair @rest, # consumes all unrecognised name/value pairs ) { ... }

    This seems a popular feature request: give Perl 5 something similar to Perl 6's named parameters.

    Querying Parameters

    ?$x peek ahead to the next arg ??$x peek ahead and see if there is a next arg ?@a peek ahead and copy all remaining args ?%h peek ahead and copy all remaining key/val arg pairs ?{ code } execute some code without consuming any args

    Sometimes you want to find out some extra information about the arguments and the state of argument processing. With @_ available, this can be done, if messily; if @_ isn't populated (see the "@_ Suppression" thread), then it becomes harder/impossible, unless some other mechanisms are added.

    @_ suppression

    @_ will not be set, unset or localised on entry to or exit from a signatured sub; it will still be the @_ of the caller. But any use of @_ within the lexical scope of sub a sub will warn.

    Aliasing and Read-only variables

    sub foo { # the lexical vars $a, @b and %c are aliased to the things poi +nted # to by the reference values passed as the first three argumen +ts: \$a \@b, \%c, # $d is aliased to the fourth arg: *$d, # $e is aliased to the fifth arg, but at compile time, any us +e # of $e in lvalue context within this lexical scope is a compi +le # time error: *$e :ro, # the elements of @f are aliased to any remaining args, # i.e. a slurpy with aliasing ...: *@f # .. or a slurpy hash; every second remaining arg is aliased t +o # the hash's values: *%g ) { ... }

    Type and Value Constraints and Coercions

    sub f( $self isa Foo::Bar, # croak unless $self->isa('Foo +::Bar'); $foo isa Foo::Bar?, # croak unless undef or of tha +t class $a!, # croak unless $a is defined $b is Int, # croak if $b not int-like $c is Int?, # croak unless undefined or in +t-like $d is PositiveInt, # user-defined type $e is Int where $_ >= 1, # multiple constraints $f is \@, # croak unless array ref $aref as ref ? $_ : [ $_ ] # coercions: maybe modify the +param ) { ...};

    It seems that people express a desire to be able to write something like:

    sub f (Int $x) { ... }

    as a shorthand for for something like:

    sub f ($x) { croak unless defined $x && !ref($x) && $x =~ /\A-?[0-9]+\Z/; ....; }

    Similarly people want

    sub f (Some::Arbitrary::Class $x) { ... }

    as a shorthand for

    sub f ($x) { croak unless defined $x && ref($x) && $x->isa(Some::Arbitrary::Class); ...; }

    Furthermore, there are also Perl 6 generic constraints:

    sub f ($x where * < 10*$y) { ... }

    Scope and Ordering

    We need to determine and document how the various parts of a signature behave as regards to lexical scope, visibility, tainting and ordering of things like default expressions and constraints.

    dave_the_m proposes for lexical scoping that:

    sub f($a, $b, $c, ... ) { BODY; }

    Is logically equivalent to:

    sub f { my $a = ....; my $b = ....; my $c = ....; ....; BODY; }

    In particular, each parameter element is independent taint-wise, and each parameter variable has been fully introduced and is visible to default expressions and the like in further parameters to the right of it.

    Miscellaneous suggestions

    This last post contains are a few random suggestions that people have made at various times.

Custom date calculations using Date::Manip
No replies — Read more | Post response
by cavac
on Nov 27, 2019 at 12:57

    Some time ago, i uploaded Acme::September::Eternal to cpan. Then, on request by stevieb at Re^3: Help with my crap, i got a variant of that project.

    To quote: "I'm Canadian, so for us folk, it would be preferred if it was eternaldecemberize() where there's a single month of warm weather (August), and the rest December"

    I have uploaded Acme::December::Eternal to CPAN. But before that, i wrote a small test program to check out the math involved. The premise is that the year starts on 1st of August, and except of August everything else is the month of December. Let's take a look (you might need to click, i've put most of the article into a readmore tag)...

    Note: This is still technically incorrect, because there have been instances where countries skipped days on the calendar. For example, Samoa skipped the 30th of December 2011 so they could get to the other side of the dateline for some business reason. I'll have to fix my CPAN module to account for that kind of stuff.

    print $outstring, "\n";

    We output the calculated date string and we are done.

    Note 2: Calculating exact dates in the future is not possible, no matter how good your date library is. Not only for reasons like countries skipping (or adding) days, switching calendars, changing timezones on short notice or redefining daylight savings time (or banning/reintroducing it) willy-nilly after every change of government. No, even if you could fix all that (hint: go into politics), the nice folks at the International Earth Rotation and Reference System Service who keep our atomic clocks in sync with our solar system release a new Bulletin C twice a year to tell you if there is going to be a leap second at the end of the six month period. So, good luck estimating future timestamps ;-)

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
a lot of the CPAN big hitters have gone
3 direct replies — Read more / Contribute
by tobyink
on Nov 26, 2019 at 03:50

    I know I'm guilty of disappearing for extended periods myself. I understand that family, jobs, life can give people less time to contribute to open source projects. But it's somewhat concerning that a lot of major CPAN authors who have written some pretty useful modules seem to be disappearing lately. None of the following authors have made a release in the last 12 months:

    • ADAMK - Params::Util, DBD::SQLite
    • DOY - Eval::Closure
    • FLORA - Term::ReadLine
    • KENTNL - HTML::Tree
    • MSCHILLI - Log::Log4perl
    • MSCHWERN - Test::More, Method::Signatures
    • NUFFIN - KiokuDB, Try::Tiny
    • RCLAMP - File::Find::Rule, Pod::Coverage
    • RSRCHBOY - MooseX::AttributeShortcuts
    • STEVAN - Moose
    • TIMB - DBI, Devel::NYTProf
    • SIMONW - Module::Pluggable

    (Honorable mentions to INGY, DAGOLDEN, and RSAVAGE who have barely released anything in the last 12 months.)

    Many of their projects have gotten new maintainers, and there are always new CPAN authors coming up and releasing some great new things, but we do seem to be losing some key people who have made important contributions to the Perl ecosystem.


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, 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, 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.
  • Log In?
    Username:
    Password:

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

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (5)
    As of 2020-01-19 15:59 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?
      Notices?