http://www.perlmonks.org?node_id=479

If you have a question on how to do something in Perl, or you need a Perl solution to an actual real-life problem, or you're unsure why something you've tried just isn't working... then this section is the place to ask.

However, you might consider asking in the chatterbox first (if you're a registered user). The response time tends to be quicker, and if it turns out that the problem/solutions are too much for the cb to handle, the kind monks will be sure to direct you here.

Post a new question!

User Questions
Check that a ramdisk is mounted
2 direct replies — Read more / Contribute
by pmilne
on May 14, 2021 at 17:58
    To test whether a ramdisk has been mounted I have created a file in the mount point directory. I then test whether that file exists and if not I presume a ramdisk has been mounted there. Is there a more elegant method without needing a test file?
(WIN) Autoflush, Perl, Sleep and Powershell
2 direct replies — Read more / Contribute
by LanX
on May 14, 2021 at 11:58
    Something weird is happening when I'm starting a Perl script under powershell and redirecting STDOUT to a logfile

    PS D:\tmp> perl -E"$|=1;print $]" >.\tmp.log # writ +es log immediately PS D:\tmp> cat .\tmp.log 5.032001 PS D:\tmp> perl -E"$|=1;print $];sleep 100" >.\tmp.log # does +n't write log Terminating on signal SIGINT(2) PS D:\tmp> cat .\tmp.log # empt +y PS D:\tmp> exit d:\tmp>perl -E"$|=1;print $];sleep 100" >.\tmp.log # writ +es log immediately Terminating on signal SIGINT(2) d:\tmp> type .\tmp.log 5.032001

    What am I missing? Is this a bug in Perl or Powershell?

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

    update

    Couldn't reproduce the even after finishing sleep part anymore

    update

    OK to make sure that it's not a side effect from -E I created a (very) short script.pl

    PS D:\tmp> echo '$|=1;print $];sleep 10' > tst.pl PS D:\tmp> cat .\tst.pl $|=1;print $];sleep 10 PS D:\tmp> perl tst.pl # prints immediately 5.032001 PS D:\tmp> perl tst.pl >tmp.log Terminating on signal SIGINT(2) PS D:\tmp> cat .\tmp.log PS D:\tmp> PS D:\tmp> perl tst.pl >tmp.log # don't CTRL-c, just wait PS D:\tmp> cat .\tmp.log 5.032001

    again,

  • if I run the script without redirection I see the output immediately
  • if I redirect, the log isn't written while sleeping
  • if I terminate with CTRL c the log isn't written either
  • only if I wait 10 sec I'll see the log written
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
    Hi

    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

    === FILENAME.srt === 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

Need to get hash of arrays
6 direct replies — Read more / Contribute
by chandantul
on May 14, 2021 at 01:54

    Hello Smart monks, I have the data looks like below in separate columns and i will need to get the unique values of columns A and assign multiple values of column B Please check below data structure

    ColA | ColB | 500001| Network1| 500001| Network2| 500002| Network2| 500003| Network1| 500003| Network3|</

    I will need to assign all corrosponding values of Column B to the unique value of Column A , This will be looks like below

    $var1 => {500001 => Network1 , Netowrk2} {500002 => Netowrk2} {500003 => Netowrk1 , Netowrk3}

    I have tried by below Hash mapping but its coming with one to one mapping but i will need one to multi mappings

    @hash4{@cellp} = [@cellq];

    Code output

    {500001 => Netowrk2} {500002 => Netowrk2} {500003 => Netowrk3}

    Can you please help with proper assignment?

"" but true
3 direct replies — Read more / Contribute
by Chuma
on May 13, 2021 at 14:51

    You're probably familiar with the semi-special value '0 but true', which works like 0 in any arithmetic operation, yet still evaluates to true. You can also use '0e0' or other varieties.

    But in this case, what I'd like is a true value that acts as the "nothing value" not just in arithmetic operations, but also in string operations. So if $x has this value, if($x) is true, but $x.$y is just $y.

    One sneaky solution is control characters, like $x="\c@". That gives a true value, and printouts will look correct. But it still means that if($x.$y eq $y) will fail, and anyone who tries to use length() is going to end up very confused.

    Is there a way to do this?

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...)

    Thanks.

    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...


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