Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Seekers of Perl Wisdom

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

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
Parallel::ForkManager right approach
2 direct replies — Read more / Contribute
by Takamoto
on Oct 13, 2019 at 11:05

    This is my first attempt to process things in parallel with Parallel::ForkManager on a server. I have several subrutines to collect data through APIs. I want to perform it in parallel and then merge the results. This is my script, not elegant of course, but it runs. As I do not see a huge difference in performance (time) in running things in parallel with this script or running the single subrutines one after the other (the script let me save ~1/3 of the time), just wanted to ask for your wisdom about my script

    use Parallel::ForkManager; my $max_procs = 6; my @names = qw( 0 2 3 4 5 0 ); my @DataStructure; my $pm = Parallel::ForkManager->new($max_procs, @ARGV); $pm->run_on_finish( sub { my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_struct +ure_reference) = @_; my @results= @$data_structure_reference; if (@results){ push (@DataStructure, @results); } }); foreach my $child ( 0 .. $#names ) { my $pid = $pm->start($names[$child]) and next; my @results; if ($child eq 1){ @results=getResultsAPI_1(); } elsif ($child eq 2){ @results=getResultsAPI_2(); } elsif ($child eq 3){ @results=getResultsAPI_3(); } elsif ($child eq 4){ @results=getResultsAPI_4(); } elsif ($child eq 5){ @results=getResultsAPI_5(); } elsif ($child eq 6){ @results=getResultsAPI_6(); } $pm->finish($child, \@results); } $pm->wait_all_children;
Unit test of script fails unless Test::Warnings is used?!
1 direct reply — Read more / Contribute
by wanna_code_perl
on Oct 12, 2019 at 20:38

    Fellow Monks!

    I have a script in my latest distribution that I am adding unit tests for. I've gone with the simple caller approach:


    #!/usr/bin/perl use 5.010; use strict; use warnings; main(@ARGV) unless caller; sub main { die 'main() was run' }

    This script exits with no warnings and normal status when require'd via perl -Ibin -e 'require "script";', but die()s as expected when run directly from the commandline.


    #!perl use 5.010; use strict; use lib qw(bin); use Test::More; #use Test::Warnings ':all'; # <-- BEGIN { eval { require 'script' }; BAIL_OUT("bin/script did not load: $@") if $@; } done_testing;

    When run via make test, I get bin/load.t ........ skipped: (no reason given) and 255 exit status. When run via prove bin/load.t, I get the same:

    t/bin/00-run.t (Wstat: 65280 Tests: 0 Failed: 0) Non-zero exit status: 255

    I don't know why it's failing. Interestingly, it only failed when I started removing extraneous use lines from bin/load.t. Removing Test::Warnings was the one that stopped it from working! If the use Test::Warnings ':all'; line is uncommented, the test script succeeds.

    The BEGIN block seemingly makes no difference. The results are the same if the code is run outside of BEGIN { ... }. Also, if I add a die to the top of bin/script it (correctly) fails with the BAIL_OUT() message from bin/load.t.

    So the abnormal exit has me confused. Why is it failing, and how do I fix it? I guess the success under Test::Warnings should be a clue, but I would expect the tests to be more sensitive to warnings when Test::Warnings is included (due to the extra test it adds), not less sensitive.

Select Tcp Client
4 direct replies — Read more / Contribute
by PerlNewbie94
on Oct 12, 2019 at 16:44
    Hey Guys, I am working with a script which needs to handle multiple tcp clients. I have learned that this can be solved by using IO::Select. I have tested my server script with nc command in Linux and it is working ok. My issue is that i need to take input from user. But my client doesn't receive any information from the server till i have pressed enter on the client. My question is shouldn't $read_handler->can_read() get a value everytime there is incoming data from server? If a value is sent by server then client should be receiving it immediately? P.S. i am new to Perl and socket programming. Any kind of help would be greatly appreciated.
    use IO::Socket::INET; use IO::Select; # auto-flush on socket $| = 1; my $server_ip; my $server_port; #my $r,$w; @ARGV == 2 or die "IP and Portnumber needed"; ($server_ip,$server_port)=@ARGV; # create a connecting socket my $socket = new IO::Socket::INET ( PeerHost => $server_ip, PeerPort => $server_port, Proto => 'tcp', ); die "cannot connect to the server $!\n" unless $socket; my $read_handler = IO::Select->new(); $read_handler->add($socket); my $send_buffer; while(1) { @sockets_ready =$read_handler->can_read(); foreach my $read(@sockets_ready) { my $buffer; $buffer = <$socket>; print "$buffer\n"; } @write_ready=$read_handler->can_write(); foreach my $message(@write_ready) { my $send_buffer=<STDIN>; $message->send($send_buffer); } }
    This is my server code in case.
    #!/usr/bin/perl -w use strict; use warnings; use IO::Socket; use IO::Select; # auto-flush on socket $| = 1; my $server_ip; my $server_port; @ARGV == 2 or die "IP and Portnumber needed"; ($server_ip,$server_port)=@ARGV; # creating a listening socket my $tcp_socket = new IO::Socket::INET( LocalHost => $server_ip, LocalPort => $server_port, Proto => 'tcp', Listen => 5, Reuse => 1 ); die "cannot create socket $!\n" unless $tcp_socket; print "server waiting for client connection on port $server_port\n"; #Create readhandlers with select my $read_select = IO::Select->new(); $read_select->add($tcp_socket); #version send to server my $Version ="Hello <VERSION>\n"; #hash for client my %clients; while(1) { my $new_readable; my $nick; ($new_readable)=IO::Select->select($read_select,undef,undef,0); foreach my $read(@$new_readable) { if($read==$tcp_socket) { my $new_connection = $read->accept(); $new_connection->send($Version); $read_select->add($new_connection); } else { my $buf; my $msg; $buf=<$read>; if($buf) { my @sockets = $read_select->can_write(); #returns a array + of handl$ foreach my $sck(@sockets) { $sck->send("$buf\n"); } } else { $read_select->remove($read); } } } } $tcp_socket->close();
MongoDB ObjectID
1 direct reply — Read more / Contribute
by betacentauri
on Oct 12, 2019 at 13:36

    O monks,

    I can't for the life of me figure out the proper way to prepare HTML references to MongoDB documents. I'm using Dancer2 with MongoDB 3.4.15, and Template Toolkit. I'm fairly new to these three monsters, and it shows.

    I can select and display documents from a collection in an HTML table. When a table row is clicked, I want to show a modal window filled with the document data, then possibly edit some data, then possibly save it back.

    My problem lies in how to build the table. I envision every row provisioned with an onclick script which receives the document _id and uses it as a key to bring the document from the database via AJAX for the modal to be filled. Now, how to go about presenting _id, which is an ObjectID, to Template Toolkit as valid HTML content for the script to consume it? As per Data::Dumper, each _id field data is '_id' => bless( {'oid' => '...funny characters...' }, 'BSON::OID' ). Understandably, I can't seem to make any other than HASHrefs to reach my HTML.

    Should I serialize every ObjectID on the way to HTML, then deserialize it to get an ObjectID again? How to achieve this? If I were to extract oid, then convert it to some visible form, could this be done into the template? I've tried with a $project stage in the aggregation pipeline but I don't understand how or where to convert oids to strings.

    Am I misdirected? Is there a simple way to do this? Thank you in advance.

Can't find application class in @INC when starting Mojolicious-generated app
1 direct reply — Read more / Contribute
by djevox
on Oct 12, 2019 at 09:56

    I'm completely new to Perl, so please be gentle. I generated a mojolicious app with the command mojo generate app first-app. It generated the app structure that should allow a running example when running the dev server with morbo ./script/first-app.

    The file structure looks like this:

    My error when running morbo ./script/first-app in the root of the project directory is this error:

    Can't load application from file "/home/djnorrisdev/Documents/mojo-pra +ctice/first-app/script/first-app": Can't find application class "firs +t-app" in @INC. (/home/djnorrisdev/Documents/mojo-practice/first-app/ +lib /home/djnorrisdev/perl5/perlbrew/perls/perl-5.30.0/lib/site_perl/ +5.30.0/x86_64-linux /home/djnorrisdev/perl5/perlbrew/perls/perl-5.30. +0/lib/site_perl/5.30.0 /home/djnorrisdev/perl5/perlbrew/perls/perl-5. +30.0/lib/5.30.0/x86_64-linux /home/djnorrisdev/perl5/perlbrew/perls/p +erl-5.30.0/lib/5.30.0) Compilation failed in require at (eval 72) line 1

    I tried using the full path for morbo (as mentioned in a 6 year old SO post), but that gives the same error as above. That command was this: /home/djnorrisdev/perl5/perlbrew/pls/perl-5.30.0/bin/morbo ./script/first-app

    Running morbo script/first-app gives the same error.

    I'm guessing anyone familiar with a full mojolicious app would be familiar with the script file, but here's the contents of script/first-app:
    #!/usr/bin/env perl use strict; use warnings; use Mojo::File 'curfile'; use lib curfile->dirname->sibling('lib')->to_string; use Mojolicious::Commands; # Start command line interface for application Mojolicious::Commands->start_app('first-app');

    Considering this is a mojolicious-generated app, I would assume it should not get an @INC error and run with morbo without issue. Does anyone have insight into this?

    Edit: I forgot my env info. I'm on ubuntu 18.04LTS and am using Perl 5.30.0. I do have perlbrew installed also, and all my editing is done in vscode.

Problems passing hash reference
4 direct replies — Read more / Contribute
by baxy77bax
on Oct 11, 2019 at 12:36

    I am having problem understanding why this code is not working:

    # my Test package ( package Test; use strict; use Data::Dumper; sub new { my ($class) = @_; my $self->{_name} = __PACKAGE__; $self->{_suffix} = ".sp"; bless $self, $class; } sub make{ my ($self,$arg) = @_; if (ref $arg eq 'ARRAY'){ foreach my $t (@{$arg}){ if (ref $t eq 'HASH'){ _ss($t) }; } } } sub _ss { my ($self, %arg) = @_; print Dumper(\%arg); } 1; ## and my test scritp( use strict; use lib "./"; use Test; my $t = Test->new(); my @a; my %t = (1 =>"1", 2 => "2"); push(@a,\%t); $t->make(\@a);
    When I execute I get
    $VAR1 = {};
    Why ?? How to pass a hash ref to _ss()
how to get stash name of SV?
3 direct replies — Read more / Contribute
by xiaoyafeng
on Oct 11, 2019 at 03:55

    As described in perlapi, you can get stash of an SV by SvSTASH, but the following code always crashes!

    use strict; use warnings; package dd; our $dd = "hello world"; main_pp(\$dd); use Inline Config => BUILD_NOISY => 1, CLEAN_AFTER_BUILD => 0; use Inline 'C' => Config => ccflagsex => '-g'; use Inline 'C' => <<'CODE'; int main_pp(SV* rx){ SV* x = get_sv("dd::dd", 0); /* below 2 statement both crash! */ // printf("stash is %s \n", HvNAME(SvSTASH((SV*)SvRV(rx)))); // printf("stash is %s \n", HvNAME(SvSTASH(x))); printf("pv is %s \n", (SvPVX(x))); HV* h = gv_stashpv("dd", 0); HE* hash_entry; SV* sv_key; SV* sv_val; int num_keys = hv_iterinit(h); for (int i = 0; i < num_keys; i++) { hash_entry = hv_iternext(h); sv_key = hv_iterkeysv(hash_entry); sv_val = hv_iterval(h, hash_entry); printf("%s => %s\n", SvPV(sv_key, PL_na), SvPV(sv_val, PL_na)); } return 0; } CODE
    Please help! Thanks in advance!

    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Combine coverage reports
2 direct replies — Read more / Contribute
by ovedpo15
on Oct 10, 2019 at 15:30
    Hello Monks
    I have some tests there being run separately and for each one of them I have a coverage report using Devel::Cover.
    I would like to combine those two reports into one main report. What is the proper way to do so?
    I could write a wrapper which executes this tests but I have to run them separately.
    For example:
    /path1/to/test1/cover_db /path2/to/test2/cover_db
    How to combine those two reports?
Extra quotes doing SQL insert from Perl to CSV.
4 direct replies — Read more / Contribute
by JamieJ
on Oct 10, 2019 at 11:34

    When I write to a csv file from Perl using SQL Insert, I get either 0123 or """0123""", but I need "0123". Neither concatenation nor regex seem to resolve the issue.

    Here's my code:

    my $dbh = DBI->connect(qq{DBI:CSV:csv_eol=\n;csv_sep_char=\\,;}); $dbh->{'csv_tables'}->{'Table'} = {'file' => 'data.csv','col_names' => + ["num","id"]}; #Setup error variables $dbh->{'RaiseError'} = 1; $@ = ''; ## Attempts to change $num ##$num = '"'.$num.'"';## this causes """0123""" ##$num = "\"$num\"";## this causes """0123""" even if I additionally d +o this: ## $num=~s/"""/"/g; ##$num = " ".$num;## causes " 0123" VERY CLOSE. Try next line: ##$num=~s/ //g;## This causes 0123 ##$num = "".$num; ## causes 0123 ##$num = "'".$num."'";## causes 123 my $value = "\'$num\',\'$id\'"; my $insert = "INSERT INTO Table VALUES ($value)"; my $sth = $dbh->prepare($insert); $sth->execute(); $sth->finish(); $dbh->disconnect();

    I would like to have the output of $num to end up being "0123" in the CSV, but instead I get 0123 or """0123""" or " 0123"

    Any suggestions?

Config::Any does not complain when Config::Tiny is not installed
1 direct reply — Read more / Contribute
by kaldor
on Oct 10, 2019 at 10:03

    Hi all,

    I'm using Config::Any to read INI files that don't have ".ini" extension. Config::Any::INI requires Config::Tiny, but when Config::Tiny is NOT installed, the following code doesn't crash (as I would expect) :

    use Config::Any; my @plugins = ('Config::Any::INI'); my $cfg = Config::Any->load_files( {files => \@filepaths, force_plugin +s => \@plugins} );

    What am I missing here?

Add your question
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.
  • 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 about the Monastery: (3)
    As of 2019-10-14 05:57 GMT
    Find Nodes?
      Voting Booth?