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. Post a new question!

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.

User Questions
Using PerlApp or PAR with modules with data dependenciess
No replies — Read more | Post response
by Anonymous Monk
on Dec 15, 2017 at 11:59

    Hello monks

    I am trying to pack into an executable (exe) a simple perl script containing a module with data dependencies. I am failing. I am working with ActiveState/PerlApp, but I would like to be able to solve the problem even with Strawberryperl/PAR-PP. I am simply trying to pack the following script with one module.

    use Lingua::Sentence; my $splitter = Lingua::Sentence->new("en"); my $text = 'This is a paragraph. It contains several sentences +. "But why," you ask?'; print $splitter->split($text);

    The problem has to do imho with this line

    # Try loading nonbreaking prefix file specified in constructor my $dir = dist_dir('Lingua-Sentence');

    Once generated the exe there is no more dist_dir, I guess (?). Of course I can twik this line of the module code (for example setting a $dir of my choice (and give my client both exe and the files upon which the module depends), but I do not thing this is the right way to do it. What do you think? PS: this applies to all other modules using some sort of data/files in their module folder.

Appconfig module question
4 direct replies — Read more / Contribute
by hveneticus
on Dec 15, 2017 at 10:34

    I have to read a configuration file that contains lines like these ones:

    VAR=/path/to/ AMB=cer DIRSKE=${VAR}${AMB} SCRIPT=${DIRSKE}/script.sh

    After a search, I found that module Appconfig can be the right one. I've read its documentation more and more, but I think I don't really understand how it works (honestly, it is a bit harder to read). Consider also that I'm only a beginner in Perl. My problem is the variable named DIRSKE. Appconfig can expand the value as in a shell script, but I can't understand how do it when I have two of them in the same line.

    #!/usr/bin/perl use strict; use warnings; use AppConfig qw(:expand); my $config = AppConfig->new({ CASE => 1, GLOBAL => {EXPAND => EXPAND_ALL} }); $config->define("VAR=s"); $config->define("AMB=s"); $config->define("DIRSKE=s"); # Maybe this is wrong, but what else? $config->define("SCRIPT=s"); #read configuration file $config->file("./file.conf"); #some print print "Valore VAR -> ".$config->VAR()."\n"; print "Valore AMB -> ".$config->AMB()."\n"; print "Valore DIRSKE -> ".$config->DIRSKE()."\n"; print "Valore SCRIPT -> ".$config->SCRIPT()."\n";

    The output is:
    Valore VAR -> /path/to/ Valore AMB -> cer Valore DIRSKE -> Valore SCRIPT -> /script.sh

    I'd like to have something like:
    Valore VAR -> /path/to/ Valore AMB -> cer Valore DIRSKE -> /path/to/cer Valore SCRIPT -> /path/to/cer/script.sh

    Am I using the correct module?
    If yes, can I have a suggestion on how to do it?

    Thanks!

sort HoH by second level values in specific order
3 direct replies — Read more / Contribute
by lener
on Dec 15, 2017 at 10:18
    Dear Monks, I have a Hash of Hashes, in which the first level contains the names of nodes and the second level contains values for their 'cores' and 'memory', it looks like this:
    $free_space = { "node1" => { "cores" => 12, "mem" => 200 }, "node2" => { "cores" => 12, "mem" => 500 }, ... }
    What I'd like to do is print it out while sorting by 'cores' (descendingly) first, 'memory' (descendingly) second and nodenames (ascendingly) last. So sort by cores, and if the number of cores is equal then sort by memory, if both are equal then sort lexicographically by the node names. It's supposed to look like this:
    cores memory node ----- ------ ---- 12 400 node456 12 400 node534 12 350 node23 11 500 node12 11 200 node3 10 900 node10
    I've tried doing it "manually" by creating a new HoHoA, where the 'cores' values are first-level keys, 'memory' values are second-level keys and the array holds the names of the nodes, then printing it simply by sorting level by level, like this:
    my %CoreMemNodes = (); #HoA <free_cores> -> <free_mem> -> (node1,node2 +,..) foreach my $node (keys %free_space) { push @{ $CoreMemNodes{$free_space{$node}{'cores'}}{$free_space{$no +de}{'mem'}} }, $node; } foreach my $free_cores (sort { $b <=> $a } keys %CoreMemNodes) { foreach my $free_mem (sort { $b <=> $a } keys %{ $CoreMemNodes{$fr +ee_cores} }) { foreach my $node (sort @{ $CoreMemNodes{$free_cores}{$free_mem +} }) { print "SORTED:$free_cores $free_mem $node\n"; } } }
    Is there a more efficient solution?
Array Plus Operator
1 direct reply — Read more / Contribute
by SleepyJay
on Dec 15, 2017 at 09:41
    I am deep in some legacy code (not written by me) that looks like this (it's surrounded by an if):
    @{ $self->bar || +[] }

    What's with that '+' in there? I mean, I get that it is usually used for disambiguation (e.g. @{ $self->bar || +shift }). But, what makes this plus needed?

    (I'm not a Perl beginner, but I have never seen Perl like this: is this a dumb question?)

Win32::Sound constants are weird
No replies — Read more | Post response
by Ralesk
on Dec 15, 2017 at 09:24

    Esteemed Monks,

    I was dumb and accidentally anded some flags instead of orring them at some point when I wrote the part of the software that employs Win32::Sound I would have found out way earlier, had SND_ASYNC not been 1, and so silently working as intended...

    Today I found the bug, replaced things with bitwise ors, and wondered why this could ever have worked before, and it seems that in weird situations (such as the flags being used in the argument list of Win32::Sound::Play), the constants behave completely non-DWIMly.

    So here's some examples:

    C:\>perl -E "use Win32::Sound; say Win32::Sound::SND_ASYNC; say Win32: +:Sound::SND_LOOP; say Win32::Sound::SND_NODEFAULT;" 1 8 2

    This should mean that SND_ASYNC and (as I erroneously wrote) SND_NODEFAULT is 0, right? 1 & 2 is zero, we all know that. Those two orred together is 3.

    ... Win32::Sound::Play($filename, Win32::Sound::SND_ASYNC & Win32::Sound:: +SND_NODEFAULT); ...

    Lo and behold, that thing there has SND_ASYNC set. No, it's not a precedence issue, it would be the same if the bit construct were surrounded by an extra set of parentheses.

    C:\>perl -E "use Win32::Sound; say Win32::Sound::SND_ASYNC & Win32::So +und::SND_NODEFAULT;" 1 C:\>perl -E "use Win32::Sound; $x = (Win32::Sound::SND_ASYNC & Win32:: +Sound::SND_NODEFAULT); say $x" 1 C:\>perl -E "use Win32::Sound; say (1 & 2);" 0 C:\>perl -E "use Win32::Sound; say ('1' & '2');" 0 C:\>perl -E "use Win32::Sound; my $as = Win32::Sound::SND_ASYNC; my $n +d = Win32::Sound::SND_NODEFAULT; say $as & $nd;" 0 C:\>perl -E "use Win32::Sound; my @as = Win32::Sound::SND_ASYNC; my @n +d = Win32::Sound::SND_NODEFAULT; say @as; say @nd; say (@as & @nd);" 1 2 1

    There it is & requires scalar values to bitwise and, so takes the length of the two list context return values, which is 1 for each because each is a one element array. Or, if anything, forcing list context on these guys seems to at least replicate the error no clue why they'd be in list context there in the original usage!

    This doesn't, however, explain why it works out of the box with |, where the list context hack doesn't:

    C:\>perl -E "use Win32::Sound; my @as = Win32::Sound::SND_ASYNC; my @n +d = Win32::Sound::SND_NODEFAULT; say @as | @nd;" 1 C:\>perl -E "use Win32::Sound; $x = (Win32::Sound::SND_ASYNC | Win32:: +Sound::SND_NODEFAULT); say $x" 3

    The only question I have is just: why?

parse html for specific things
2 direct replies — Read more / Contribute
by Gtforce
on Dec 15, 2017 at 06:07

    Hi Monks!

    I've been struggling with this data (a few months old in perl). The data comes off a html page stripped down to just this. I'm looking to pick specific things like buyQuantity1, buyQuantity2, buyQuantity3. Any advice on how to do this?

    The data:

    {"futLink":"\/live_market\/dynaContent\/live_watch\/get_quote\/GetQuot +eFO.jsp?underlying=SHREECEM&instrument=FUTSTK&expiry=28DEC2017&type=- +&strike=-","otherSeries":["EQ"],"lastUpdateTime":"15-DEC-2017 14:55:5 +3","tradedDate":"15DEC2017","data":[{"extremeLossMargin":"5.00","cm_f +fm":"21,823.45","bcStartDate":"25-JUL-17","change":"-146.90","buyQuan +tity3":"3","sellPrice1":"17,751.40","buyQuantity4":"5","sellPrice2":" +17,758.50","priceBand":"No Band","buyQuantity1":"3","deliveryQuantity +":"93,925","buyQuantity2":"2","sellPrice5":"17,775.00","quantityTrade +d":"1,09,030","buyQuantity5":"2","sellPrice3":"17,772.10","sellPrice4 +":"17,772.15","open":"18,044.00","low52":"13,140.30","securityVar":"5 +.21","marketType":"N","pricebandupper":"19,688.10","totalTradedValue" +:"2,741.00","faceValue":"10.00","ndStartDate":"-","previousClose":"17 +,898.30","symbol":"SHREECEM","varMargin":"7.50","lastPrice":"17,751.4 +0","pChange":"-0.82","adhocMargin":"-","companyName":"Shree Cements L +imited","averagePrice":"17,850.84","secDate":"14DEC2017","series":"EQ +","isinCode":"INE070A01015","surv_indicator":"-","indexVar":"-","pric +ebandlower":"16,108.50","totalBuyQuantity":"7,050","high52":"20,538.0 +0","purpose":"DIVIDEND - RS 24 PER SHARE","cm_adj_low_dt":"23-DEC-16" +,"closePrice":"0.00","isExDateFlag":false,"recordDate":"-","cm_adj_hi +gh_dt":"15-MAY-17","totalSellQuantity":"7,255","dayHigh":"18,197.90", +"exDate":"21-JUL-17","sellQuantity5":"1","bcEndDate":"31-JUL-17","css +_status_desc":"Listed","ndEndDate":"-","sellQuantity2":"1","sellQuant +ity1":"1","buyPrice1":"17,750.25","sellQuantity4":"2","buyPrice2":"17 +,750.20","sellQuantity3":"2","applicableMargin":"12.50","buyPrice4":" +17,750.00","buyPrice3":"17,750.10","buyPrice5":"17,735.05","dayLow":" +17,701.00","deliveryToTradedQuantity":"86.15","basePrice":"17,898.30" +,"totalTradedVolume":"15,355"}],"optLink":"\/marketinfo\/sym_map\/sym +bolMapping.jsp?symbol=SHREECEM&instrument=-&date=-&segmentLink=17&sym +bolCount=2"}
DBIx::Class 'select.... for update' confusion
1 direct reply — Read more / Contribute
by tomgracey
on Dec 14, 2017 at 16:17

    Hello all

    I am confused about the mechanics of 'select.. for update' under DBIx::Class (I'm using MySQL but I suppose that shouldn't matter.) So I have reduced it down to the following test case:

    my $guard = $schema->txn_scope_guard; my $rs = $schema->resultset('TestTable')->search({ status => 'available' }, { rows => 1, 'for' => 'update' }); my $id_before_update = $rs->first->id; my $updated = $rs->update({ status => 'reserved' }); $guard->commit; my $id_at_end = $rs->first->id; print "id before update: $id_before_update\nid at end: $id_at_end\n";
    The table looks like this initially:
    +----+-----------+ | id | status | +----+-----------+ | 1 | available | | 2 | available | | 3 | available | +----+-----------+

    and after execution like this:

    +----+-----------+ | id | status | +----+-----------+ | 1 | reserved | | 2 | available | | 3 | available | +----+-----------+

    The schema was created by DBIx::Class::Schema::Loader and looks like this:

    __PACKAGE__->table("test_table"); __PACKAGE__->add_columns( "id", { data_type => "bigint", is_nullable => 0 }, "status", { data_type => "varchar", is_nullable => 1, size => 255 }, );
    (with boilerplate removed). When I run the above code I get the following:
    id before update: 1 id at end: 2

    To me this seems like odd behaviour, because after $rs is selected with rows=1 it surely should only contain a single row with a single id...?

    Any idea what stupid thing have I (not) done this time?

Perl <dir_with_wildcards>
1 direct reply — Read more / Contribute
by haroyken
on Dec 14, 2017 at 02:36

    O wise monks I beseech thy help in understanding this snippet of perl:

    Basically I had files stores in multiple dir and want to assign the location of these files to an array

    E.g.

    /home/a1/data/loga1.txt (data also contains other files with different extension)

    /home/b2/data/logb2.txt

    /home/c3/data/logc3.txt

     my @array = </home/*/data/*.txt>;

    does the job but I don't understand why

    Normally I've seen the diamond operator with STDIN, etc. or filehandle. How does it work with a directories with wildcards like this ?

    Thank you very much

Why does "cpan -r" download new modules?
2 direct replies — Read more / Contribute
by jimav
on Dec 14, 2017 at 00:20

    What exactly is "cpan -r" supposed to do? The man page says it runs CPAN::Shell->recompile and perldoc CPAN says recompile() should recompile XS code for all installed dynamically-linked extensions. But in fact, it seems to download and install many other modules I never installed!

    To be sure I wasn't hallucinating, I created a brand-new user with an empty home directory, used local::lib to set up a local cpan build environment. Then ran "cpan -r" expecting it to do nothing because the new user had never installed any CPAN modules. However, it proceeded to download and install zillions of modules, until it finally failed with some unmet dependency. What causes this!?!

    Can someone explain (or point me to documentation explaining) where "cpan -r" looks to decide what modules to update, and what is the correct procedure for just rebuilding the XS code for only the modules I previously installed? Really, I just want to recover from XS breakage due to perl being updated (during an OS upgrade).

    BTW, I just did a clean Ubuntu 17.10 install (preserving only /home), so the system perl installation and library are pristine. And I never ran cpan as root, so there is no way it could have damaged the system setup (assuming there isn't a suid program lurking somewhere in cpan)

    Here's what I did:

    #Create a new user with pristine environment
    $ sudo adduser test  
    $ sudo rm -f /home/test/.*   # get rid of .profile or any other influence
    $ sudo su - test
    $ ls -a
    .  ..  .bash_history 
    # set up ~/perl5 and set environment vars for local cpan library
    $ eval "$(perl -I/path/to/other/user/perl5 -Mlocal::lib)
    $ env | grep -i PERL
    PERL_MB_OPT=--install_base "/home/test/perl5"
    PERL_MM_OPT=INSTALL_BASE=/home/test/perl5
    PERL_LOCAL_LIB_ROOT=/home/test/perl5
    PERL5LIB=/home/test/perl5/lib/perl5
    PATH=/home/test/perl5/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin
    
    # set up cpan for local builds
    $ cpan
    Sorry, we have to rerun the configuration dialog for CPAN.pm due to
    some missing parameters. Configuration will be written to
     <</home/test/.cpan/CPAN/MyConfig.pm>>
    CPAN.pm requires configuration, but most of it can be done automatically.
    If you answer 'no' below, you will enter an interactive dialog for each
    configuration option instead.
    Would you like to configure as much as possible automatically? yes I hit Enter
    Autoconfiguration complete.
    commit: wrote '/home/test/.cpan/CPAN/MyConfig.pm'
    ...
    quit
    
    # Now the craziness begins...
    # Since this test user has never installed any CPAN modules, I expected
    # "cpan -r" to do nothing.  But...
    $ cpan -r
    Loading internal null logger. Install Log::Log4perl for logging messages
    Fetching with LWP:
    http://www.cpan.org/authors/01mailrc.txt.gz
    Reading '/home/test/.cpan/sources/authors/01mailrc.txt.gz'
    ............................................................................DONE
    Fetching with LWP:
    http://www.cpan.org/modules/02packages.details.txt.gz
    Reading '/home/test/.cpan/sources/modules/02packages.details.txt.gz'
      Database was generated on Thu, 14 Dec 2017 04:29:02 GMT
    ............................................................................DONE
    Fetching with LWP:
    http://www.cpan.org/modules/03modlist.data.gz
    Reading '/home/test/.cpan/sources/modules/03modlist.data.gz'
    DONE
    Writing /home/test/.cpan/Metadata
    .......................................................
      CPAN: Recompiling A/AM/AMS/Storable-2.51.tar.gz
    
    Fetching with LWP:
    http://www.cpan.org/authors/id/A/AM/AMS/Storable-2.51.tar.gz
    Fetching with LWP:
    http://www.cpan.org/authors/id/A/AM/AMS/CHECKSUMS
    Checksum for /home/test/.cpan/sources/authors/id/A/AM/AMS/Storable-2.51.tar.gz ok
    'YAML' not installed, will not store persistent state
    Configuring A/AM/AMS/Storable-2.51.tar.gz with Makefile.PL
    Checking if your kit is complete...
    Looks good
    Generating a Unix-style Makefile
    Writing Makefile for Storable
    Writing MYMETA.yml and MYMETA.json
      AMS/Storable-2.51.tar.gz
      /usr/bin/perl Makefile.PL INSTALLDIRS=site -- OK
    Running make for A/AM/AMS/Storable-2.51.tar.gz
    cp Storable.pm blib/lib/Storable.pm
    Running Mkbootstrap for Storable ()
    chmod 644 "Storable.bs"
    "/usr/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- Storable.bs blib/arch/auto/Storable/Storable.bs 644
    "/usr/bin/perl" "/usr/share/perl/5.26/ExtUtils/xsubpp"  -typemap '/usr/share/perl/5.26/ExtUtils/typemap'  Storable.xs > Storable.xsc
    mv Storable.xsc Storable.c
    x86_64-linux-gnu-gcc -c   -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g   -DVERSION=\"2.51\" -DXS_VERSION=\"2.51\" -fPIC "-I/usr/lib/x86_64-linux-gnu/perl/5.26/CORE"   Storable.c ...
    <and much more>
    
    ...Eventually it died with some unsatisfied dependency...
    
    Fetching with LWP:
    http://www.cpan.org/authors/id/X/XA/XAOC/Pango-1.227.tar.gz
    Checksum for /home/test/.cpan/sources/authors/id/X/XA/XAOC/Pango-1.227.tar.gz ok
    ---- Unsatisfied dependencies detected during ----
    ----          XAOC/Pango-1.227.tar.gz         ----
        ExtUtils::Depends build_requires
        ExtUtils::PkgConfig build_requires
    
Problem creating http request string using apostrophe
1 direct reply — Read more / Contribute
by Bloehdian
on Dec 13, 2017 at 19:33

    Hi all,

    the following script should send an http-request to httpbin.org. But it fails with the creation of the proper request string, probably since the script interprets it as a sequence of namespaces separated in the old style using apostrophe. What am I doing wrong?

    #!/usr/bin/perl use strict; use REST::Client; my $client = REST::Client->new(); my $request=q{DELETE('https://www.httpbin.org/delete')}; print $request; eval( $client->$request ); print $client->responseCode();

    Execution leads to the following

    Can't locate object method ")" via package "DELETE('https://www.httpbin.org/delete" (perhaps you forgot to load "DELETE('https://www.httpbin.org/delete"?) at test.pl line 7.

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


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