Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

The Monastery Gates

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

If you're new here please read PerlMonks FAQ
and Create a new user.

poll ideas quest 2021
Starts at: Jan 01, 2021 at 00:00
Ends at: Dec 31, 2021 at 23:59
Current Status: Active
3 replies by pollsters
    First, read How do I create a Poll?. Then suggest your poll here. Complete ideas are more likely to be used.

    Note that links may be used in choices but not in the title.

Perl News
Improving p5p: Perl is going to stay Perl
on May 17, 2021 at 15:06
4 replies by marto
Documentation is to be overhauled
on May 14, 2021 at 10:30
2 replies by hippo
Next from inner loop only works "most of the time"
4 direct replies — Read more / Contribute
by Marshall
on May 18, 2021 at 08:31
    I wrote some code today that worked most of the time but not all of the time -> different runs of Perl produced different results.
    I have fixed the code so that it is reliable. My question is "what happens inside Perl such that my first version was unreliable?"

    I started playing a scrabble like game on my cellphone and once I got to level 108, things got hard. So I whipped out a cheater program! Pretty easy to do and my quick hack worked fine except that it made mistakes but only some of the time.

    Here is the output of a "good" run:

    list of letters or pattern: :otrwreh master_letter_freq: $VAR1 = { 'w' => 1, 'h' => 1, 't' => 1, 'o' => 1, 'r' => 2, 'e' => 1 }; list of letters or pattern: ---w thew trow list of letters or pattern:
    The letters "otrwreh" are its "vocabulary" for forming words. "r" can be repeated, but none of the other letters.
    The pattern "---w", means show all 4 letter words in the dictionary that end in "w" that are formed using only the letters "otrweh".

    All well and good until I saw this run:

    list of letters or pattern: :otrwreh list of letters or pattern: ---w thew trow whew ## this is the problem!! "w" is not allowed to repeat! list of letters or pattern: exit
    Ok, the offending unreliable code snippet:
    RESULT: foreach (@result) { my %seen; $seen{$_}++ for (split //,lc $_); foreach (keys %seen) { next RESULT if ($seen{$_} > $master_letter_freq{$_}); } print "$_\n"; }
    Once the regex does its thing on a huge list of possible words, I take out any results where a letter occurs more often in the result than in the pattern list of characters. so, "whew" should get thrown away. But evidently the next is not being executed. Sometimes the code falls through the loop and "whew" gets printed even though "w" occurs too often for the "rules".

    Now arguably using "next" in this way is not the brightest thing I've done. But when hacking, stuff happens and sometimes I try something new with Perl. This was just "throw away" code for my own amusement.

    Of course I rewrote the code using a more traditional approach like this:

    foreach (@result) { my %seen; $seen{$_}++ for (split //,lc $_); my $no_print = 0; foreach (keys %seen) { $no_print++ if ($seen{$_} > $master_letter_freq{$_}); } print "$_\n" unless $no_print; }
    So, I get the answer of "hey, don't do that!". I am curious why my hack was unreliable? It worked often enough that I figured that it was ok, until problems showed up later on. I had never used next in this way, although I have used a labeled redo before.

    Update: Now that I think about it, it could be that using the default variable $_ in both loops could be an issue. I normally would assign an explicit my variable for the loop variable. But in quick, just barf if out code, that didn't happen here.

Over-riding Catalyst's finalize_error method
1 direct reply — Read more / Contribute
by LittleJack
on May 16, 2021 at 22:19

    I would like to have a different Catalyst error page for unexpected code errors. The default (non-debug) one only says "please come back later" in 11 European languages.

    This is generated by hardcoded HTML HEREDOCs in finalize_error, which is an internal method.

    Obviously the worst thing to do would be to hack into that code inside Catalyst::Engine and the best thing to do would probably be to use this:, but I'm curious. Should I have been able to hack my own finalize_error method into Catalyst?

    I tried adding my own raw output code to the main .pm file for my site (the one which has use Catalyst in it) along the lines of

    print "Content-type: text/html\n\n<p>error</p>";
    but the browser didn't output anything.

    Then I tried adding my own hacked version of the proper internal method, along the lines of:

    sub finalize_error { my ( $self, $c ) = @_; $c->res->content_type('text/html; charset=utf-8'); $c->res->body( '<p>error</p>' ); $c->res->status(500); }

    But it told me $c was undefined.

    Should I have been able to do this, and if so how and where?


One liner with globs on Windows to parse .srt files
2 direct replies — Read more / Contribute
by LanX
on May 14, 2021 at 07:09

    Yesterday I needed a Perl one-liner ( -e ) to loop over ( -n ) several subtitle files glob*.srt to find those which are in sync with the video I had.

    Hence I needed paragraph mode ( -00 ) to see the timestamps

    === === 672 00:35:09,358 --> 00:35:11,027 Ditto ...

    trouble is cmd.exe doesn't do *glob expansion, and my git-bash didn't like the paragraph mode, most probably because of different understandings of line endings

    I ended up with something like this

    perl -00nE"BEGIN{@ARGV=<@ARGV>}say qq{=== $ARGV ===\n$_} if /ditto/i" *Filenames*

    but the BEGIN block is a bit ugly.

    Any more elegant way to do this?

    One generic workaround could be a special module wglob to do the BEGIN part with perl -Mwglob but I'd like to ask the community first...

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

Creating a Multi Level Hash from CSV
3 direct replies — Read more / Contribute
by workInProgress12
on May 12, 2021 at 15:11
    New to perl here and have been trying to figure this one out for a couple days now. I think I need nested forall loops or something along those lines. The task that needs to be done is to assign the columns to a multi level hash. So if my csv file was something like something below. Important to note that there are repeated values, which is the case for the provided sample output, (ie info 01 = info11, info02 = info12, etc.), but this is not always the case.
    header1,header2,header3.... info01,info02,info03... info11,info12,info13.. : : :
    The hash would look like (with the appropriate brackets)
    $VAR1 = { info01 => { info02 => { info03 => { info11 => { info12 => { info13 => {
    What I have right now:
    # MODULES use strict; use warnings; use Pod::Usage; use Data::Dumper; use Getopt::Long; use File::Basename; use Cwd 'abs_path'; use Data::Dumper qw(Dumper); use Text::CSV; my $csv = Text::CSV->new({ binary => 1, auto_diag => 1, sep_char => ',' }); my @columns; open(my $input, '<:utf8',"input.csv") or die; while (<$input>){ $csv->parse($_) or die "parse() failed: "; my @data = $csv->getline($input); for my $i (0..$#data) { # push @{$columns[$i]}, $data[$i]; push @{$columns[$i]}, $data[$i]; } } close $input; my %hash = map {shift @$_ => $_} @columns; use Data::Dumper; print Dumper(\%hash);
    This is giving me my values all in one line and not how is required
do $n exist in grep?
5 direct replies — Read more / Contribute
by misterperl
on May 12, 2021 at 10:32
    are the $n vars available somehow? in a statement like
    grep /^..(A|B)./,@a;
    Is $1 captured somewhere? It would be nice if $1 became an arrayref in this case?

    BTW it seems inconsistent that the parens in this statement might be moot. Seems odd to have syntax there that is meaningless in this context. If $1 was returned as an arrayref, it would make good sense, vis-a-vis over-loading et all?

Designing multiple related modules
4 direct replies — Read more / Contribute
by Bod
on May 12, 2021 at 08:06

    Not strictly a Perl question although the solution will be implemented in Perl and the modules will probably appear on CPAN...

    I am writing three, perhaps more, related modules which will have the same basic methods. The three modules will post content to different social media sites. I want to be able to use them something like this:

    my $social; if ($network eq 'Facebook') { $social = Bod::Social::Facebook->new( ... ); } if ($network eq 'Twitter') { $social = Bod::Social::Twitter->new( ... ); } if ($network eq 'LinkedIn') { $social = Bod::Social::LinkedIn->new( ... ); } unless ($social) { # Handle invalid network; } # Post text content to whichever network has been selected without car +ing which $social->post("Some test text"); # Post text and image content my $image_handle = $social->upload("images/test.jpg"); $social->post("Test text with image", $image_handle);
    There are at least three four options of how to implement this, probably more. I am looking for some advice on which way I should choose.

    1 - Three separate module
    Simply write three modules with similar names as in the code above. Each module has methods with the same names and similar new method. All social media platforms use OAuth2 so new can be largely the same.

    2 - Three modules that all inherit from one class
    Have a Bod::Social module that defines the methods. Then have modules as in the code above that inherit from Bod::Social and implement the methods. A bit like what I understand an interface to be in Java1. I don't see any advantage in this option in Perl over option 1 but there are certainly modules on CPAN that do this. Either there is good reason or they are written by people coming from stricter OOP languages.

    3 - Have a single method and Service Providers
    Have a single module that the code uses. In the new method, specify a Service Provider that is different for each social network. Each service provider implements the platform specific calls needed for interacting with the network. LWP::Authen::OAuth2 is implemented this way and it seems to work reasonably well but, again, I don't understand the advantages and disadvantages of this approach. Like this:

    my $social; if ($network eq 'Facebook') { $social = Bod::Social->new( service_provider => 'Facebook', ... , ); } if ($network eq 'Twitter') { $social = Bod::Social->new( service_provider => 'Twitter', ... , ); } if ($network eq 'LinkedIn') { $social = Bod::Social->new( service_provider => 'LinkedIn', ... , ); }

    4 - Use a Factory Class
    Use a Factory Class as we discussed here -> Factory classes in Perl
    As these modules will always run in the same environment this strikes me as overkill.

    I don't see there being a need to add new networks very frequently but it is quite possible that others will need adding. Which approach would you take or would you use a different solution I haven't considered? Why would you do it that way?

    This more general than just this application. Since writing Business::Stripe::WebCheckout I have decided that it would be useful if there was also Business::PayPal::WebCheckout that behaves exactly the same. Therefore the end user's code only has to call a different constructor and everything else gets called the same for multiple payment gateways. I am sure there will be more requirements for multiple related module.

    1 I'm not a Java programmer and only use it when I need to create simple Android apps.

    Edit 1: - Added option 4

    Edit 2: - Added reference to Business::Stripe::WebCheckout and corrected spelling errors.

weird case of memory corruption?
3 direct replies — Read more / Contribute
by perltux
on May 11, 2021 at 23:03
    Hi, I have come across a very weird problem while trying to use Tk::ProgressBar.
    Basically when running the following code, the output of the Label() after creating the ProgressBar seems to contain random bytes of the source code of the script itself rather than the value of the variable.

    here is the example script:

    #!/usr/bin/perl use strict; use warnings; use Tk; use Tk::ProgressBar; my %pid=(ex1=>{as=>'temp', val=>'-21.5'}); my $mw=MainWindow->new(); my $tmpbar=$mw->Frame()->pack( -padx=>30 ); PBar( \$tmpbar, \$pid{ex1}{val}, '-30', '70' )->pack(); $tmpbar->Label( -textvariable => \$pid{ex1}{val} )->pack(); $tmpbar->Label( -text => "$pid{ex1}{as}" )->pack(); print STDOUT "val Labels: $pid{ex1}{val}\n"; MainLoop; sub PBar { my($frame, $val, $min, $max)=@_; print STDOUT "val PBar1: $$val\n"; my $pbar=$$frame->ProgressBar( -anchor=>'s', -width=>40, -length=>500, -blocks=>100, -gap=>1, -resolution=>0.5, -variable=>$val, -from=>$min, -to=>$max ); print STDOUT "val PBar2: $$val\n"; return $pbar; }
    when running this script you will see that the Label under the vertical ProgressBar instead of containing the value of $pid{ex1}{val}, prints out three random bytes that appear to be from the source of the script itself.

    What is happening here? Memory corruption? ::confused::

    Also (this is my second question), why does ProgressBar modify the value of $pid{ex1}{val} rather than just reading it?
Perl Tk canvases / abuse...
2 direct replies — Read more / Contribute
by Montain_Gman
on May 11, 2021 at 17:39

    So I have found using perl canvases to debug problems; and visualize things in my field can be quite easy and fast to do. Anyway what I've found is that if I do more than say 400x400 pixels worth of stuff on a canvas, it tends to bog down; and basically it will hang.

    If i stay at say 200x200; the canvas behaves fast and I just don't get this problem. I have found (maybe superstitiously); that using idletasks to break things up helps, but I'm not sure exactly what is going on. I suspect without it, I am flooding some queue inside TK. There also seems to be a relationship with the hang and the amount of memory I am using.

    Anyway I can't post my 'real' script, as it's tied to real work. Essentially i need to simulate a legacy graphics system, and I'm using perl/tk to test things out before we do the real work on the target. My real resolution I need to hit is just over 400x400; but if i operate it that way, I can generally only get 1-2 images displayed before it will hang. (200x200; runs nice) So i created this little script to just see if i could get the same thing to happen to post here, and it generally has the same issue. If you run this, you can then use the mouse (press and hold, move, and release) to draw lines. Hitting go will redraw the back ground. If you do those things 2-3 times; especially if you make the resolution a bit higher; it is locking up for me.

    Can anyone enlighten me on what can be done to avoid this, or what is happening under the hood? Is there an easier way to just do straight pixel level screen outputs? (image magic ? I tried getting that to work but had issues on my work machine...) So would rather just stick with TK because it is very lightweight to support. (easy to install / support; anyone with perl 5.8 already has it too...)


    ONE last thing; in reviewing this; I found I am not clearing TAGS array. So that will keep eating more memory. But even if you do @TAGS =(); if you run the script enough; you'll still see the same thing happening. So that seems to be a clue; that it's a memory thing...

6 months in the Monastery
No replies — Read more | Post response
by Bod
on May 15, 2021 at 18:13

    Today is six months since I created an account here in the Monastery...

    Seldom have more than a few days passed without me kicking myself that I didn't do so much, much earlier. I have been writing Perl code since the mid-1990's but have learnt more in the last six months than in most of the time before. I managed to get quite a bit of 'stuff' working, mostly web based but also quite a few client tools. Even a handful of GUI tools using Tk. Over the years I has to do some C++ coding as part of my physics degree which I did not get on with and knew I never wanted to revisit... I've had a couple of brushes with Java including recently to create a couple of simple Android apps. But it has always been Perl that has been the language of choice.

    When I needed to do something, I found out just enough to make it work. Then didn't go any further. Why would I? I didn't know there was a better way to do things!

    A great example was when I posted some code and suddenly found out about placeholders in database queries...I had vaguely heard about the things but thought they were just for reusing one query multiple times. I soon found out they were a lot more useful than that. So useful in fact that all my code is slowly being converted.
    Re^5: Splitting the records into multiple worksheets

    The Monastery changed all that from almost immediately entering. Straight away I was implored to use strict. Something I knew of but didn't understand. I thought it was a pain and made coding much slower. But I tried using it and, yes, I have to be more careful with my coding but that's no bad thing. Now all my code has use strict at the start. Just today I've refactored a script to include it and had to change 638 lines, mostly adding my to the start!

    All my code now uses Template's where appropriate. All thanks to the Monastery. Yes, it was quite a learning curve but has enabled me to refactor an entire website and incorporate AB Testing right into the core. We just create test templates rather than having to duplicate all the code. So much easier to create, test and maintain. Certainly worth the learning curve.

    My blind uncle now has automated curtains thanks to Controlling USB on Raspberry Pi which quite possibly would never have been successfully completed without the help of fellow Monks.

    Plus, I have published a module on CPAN - Business::Stripe::WebCheckout
    Something else that almost certainly would not have happened without the help and encouragement of so many Monks

    Thanks for making the last 6 months sch a great period of learning....
    Here's to plenty more time. Hopefully, over time I will be able to pass something on to new Monks.

PerlMonks Discussions
PerlMonks on the community dashboard?
3 direct replies — Read more / Contribute
by 1nickt
on May 15, 2021 at 10:09

    This is a great idea for a "Grafana-ish" community dashboard collating metrics from various Perl sites and communities. Should PerlMonks offer to participate? (Sadly the author did not mention us in a list of resources he contemplates metering initially.)

    The way forward always starts with a minimal test.
Log In?

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

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2021-05-18 21:29 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (185 votes). Check out past polls.