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
perl built with -DDEBUGGING causes "failed to extend arg stack" error with XS modules
No replies — Read more | Post response
by parv
on Jul 24, 2021 at 17:44

    I recently built perl 5.32.1 with -DDEBUGGING & DateTime 1.54 from source (Ports, FreeBSD 13-STABLE). Now use of DateTime results in "failed to extend arg stack" (a solution seems not likely any time soon, tagged as "low serverity) ...

    # perl -MDateTime -e0 panic: XSUB Package::Stash::XS::list_all_symbols (XS.c) failed to exte +nd arg stack: base=801cff418, sp=801cff480, hwm=801cff440 Compilation failed in require at /usr/local/lib/perl5/site_perl/mach/5 +.32/DateTime/Duration.pm line 12. BEGIN failed--compilation aborted at /usr/local/lib/perl5/site_perl/ma +ch/5.32/DateTime/Duration.pm line 12. Compilation failed in require at /usr/local/lib/perl5/site_perl/mach/5 +.32/DateTime.pm line 14. BEGIN failed--compilation aborted at /usr/local/lib/perl5/site_perl/ma +ch/5.32/DateTime.pm line 14. Compilation failed in require. BEGIN failed--compilation aborted.

    What good is -DDEBUGGING now if it XS modules cannot run.

    Back to building perl sans -DDEBUGGING ...

Inline::C : passing parameters to functions, modifying by reference
5 direct replies — Read more / Contribute
by bliako
on Jul 22, 2021 at 19:54

    Dear Monks,

    I have spent quite some time in trying to do a seemingly simple task with Inline::C, that of passing a reference to a function and the function modifying it so that caller gets results back. I don't want to use the return() mechanism, so my function looks like int func(SV *inp, SV *out); inp is a readonly ref and out is the ref I would like to write to.

    I have 3 cases I would like to deal with:

    1. out is an arrayref, e.g. my @inp; my @out; func(\@inp, \@out); In this case I want to remove all elements of @out if any and then make it a 2D array of 5cols and 3rows, containing the number 42.

    2. out is a scalar, e.g. my @inp; my $out; func(\@inp, $out); In this case I want to make $out an arrayref and proceed to fill it as above, so that caller can dereference as my @out = @$out.

    3. out is a scalarref, e.g. my @inp; my $out; func(\@inp, \$out); In this case I want to find if its dereference, e.g. $out is a ref to any array or hash, or just a plain scalar. If it's a plain scalar I would like to make it an arrayref and proceed as above, so that caller can dereference as my @out = @$out.

    Can anyone help me to fill any of the blanks in this advent calendar of perlguts?

    Here is a test script testing each case.

    use strict; use warnings; use Test::More; use Inline C => Config => BUILD_NOISY => 1, clean_after_build => 0, warnings => 10, ; use Inline C => <<'EOC'; #include <stdio.h> // checks if array is indeed an arrayref and sets array_sz to its size + and // returns 1 else returns 0 (not an array) int is_array_ref( SV *array, size_t *array_sz ){ if( ! SvROK(array) ){ fprintf(stderr, "is_array_ref() : warning, i +nput '%p' is not a reference.\n", array); return 0; } if( SvTYPE(SvRV(array)) != SVt_PVAV ){ fprintf(stderr, "is_array_r +ef() : warning, input ref '%p' is not an ARRAY reference.\n", array); + return 0; } // it's an array, cast it to AV to get its len via av_len(); // yes, av_len needs to be bumped up, it's $#array int asz = 1+av_len((AV *)SvRV(array)); if( asz < 0 ){ fprintf(stderr, "is_array_ref() : error, input arra +y ref '%p' has negative size!\n", array); return 0; } *array_sz = (size_t )asz; return 1; // success, it is an array and size returned by ref, abo +ve } int func( SV *inp, SV *out ){ AV *av, *av2; size_t i, j, asz; if( is_array_ref(out, &asz) ){ printf("Case1: @out\n"); // we have an \@R, e.g. func(\@R) av = (AV *)SvRV(out); // but first clear any contents if( asz > 0 ) av_clear(av); } else if( SvROK(out) ){ printf("Case3: \\$out\n"); // we have a scalar ref, e.g. func(\$x) av = newAV(); sv_setsv(SvRV(out), (SV *)av); } else { printf("Case2: $out\n"); // we have a scalar e.g func($x); av = newAV(); sv_setsv(out, (SV *)av); } // and fill it in for(i=0;i<5;i++){ av2 = newAV(); av_extend(av2, 3); av_push(av, (SV *)av2); for(j=0;j<3;j++){ av_store(av2, j, newSViv(42)); } } return 0; // success } EOC my @inp = (1..5); my @out; my $T = 'Case1'; is(func(\@inp, \@out),0, "$T: called success."); is(scalar(@out), 5, "$T: rows are 5"); for(my $i=0;$i<5;$i++){ ok(ref($out[$i])eq'ARRAY', "$T : item $i is ARRAYref."); is(scalar($out[$i]), 3, "$T : it has 3 elements."); for(my $j=0;$j<3;$j++){ is($out[$i]->[$j], 42, "$T : it's value is 42."); } } $T = 'Case2'; my $out; is(func(\@inp, $out),0, "$T: called success."); is(ref($out)eq'ARRAY', "$T: it is now an ARRAYref."); @out = @$out; is(scalar(@out), 5, "$T: rows are 5"); for(my $i=0;$i<5;$i++){ ok(ref($out[$i])eq'ARRAY', "$T : item $i is ARRAYref."); is(scalar($out[$i]), 3, "$T : it has 3 elements."); for(my $j=0;$j<3;$j++){ is($out[$i]->[$j], 42, "$T : it's value is 42."); } } $T = 'Case3'; $out = undef; is(func(\@inp, \$out),0, "$T: called success."); is(ref($out)eq'ARRAY', "$T: it is now an ARRAYref."); @out = @$out; is(scalar(@out), 5, "$T: rows are 5"); for(my $i=0;$i<5;$i++){ ok(ref($out[$i])eq'ARRAY', "$T : item $i is ARRAYref."); is(scalar($out[$i]), 3, "$T : it has 3 elements."); for(my $j=0;$j<3;$j++){ is($out[$i]->[$j], 42, "$T : it's value is 42."); } } done_testing();

    thanks in advance, bw, bliako

How Perl decides where a variable ends and text starts: Match variables in string interpolation
1 direct reply — Read more / Contribute
by davido
on Jul 22, 2021 at 18:14

    Once in awhile Perl still surprises me.

    This code is obviously broken:

    my ($left, $right) = qw(abc def); print "$left_$right\n";

    The problem is that interpolation causes Perl to want to print a variable $left_ and $right, but we declared $left and $right. There are several ways to fix this, two of which are:

    print "$left\_$right\n"; print "${left}$right\n";

    ...and of course you could just use the concatenation operator, but then I wouldn't have anything to puzzle over.

    But observe the following:

    my $string = "abcd"; if ($string =~ m/(ab)(cd)/) { print "$1_$2\n"; }

    The output is ab_cd. So in this case Perl automatically treated that interpolation as "${1}_$2\n" without me telling it to do so. I've looked over The Gory details of parsing quoted constructs and haven't found an explanation. I assume that in the case of numbered regex variables, Perl decides that if the variable starts with a numeric digit, the identifier must end when there are no more numeric digits. Is this behavior reliable? Is it documented? Is it likely to ever change?

    I'm asking because I found it in a code review and was sure it was broken until we talked it over and tested to verify the behavior was to parse "$1_$2\n" as $1 . '_' . $2 . "\n" even though we would prefer to disambiguate using \ or ${n}.

    Update: I do see in perldata: Identifier-parsing:

    Meanwhile, special identifiers don't follow the above rules; For the most part, all of the identifiers in this category have a special meaning given by Perl. Because they have special parsing rules, these generally can't be fully-qualified. They come in six forms (but don't use forms 5 and 6):

    1. A sigil, followed solely by digits matching \p{POSIX_Digit}, like $0, $1, or $10000.

    I don't know that this is worded quite right, because $1_ could be construed as NOT being an identifier consisting solely of digits. But it's the closest thing I can find to an explanation. But I'll take that as answering my own question: Yes, it's intentional and documented behavior.


    Dave

Question regarding a regex
7 direct replies — Read more / Contribute
by CrashBlossom
on Jul 22, 2021 at 14:34
    Hello Monks,
    I would like some help in understanding the regular expression in the following code:
    sub TextFile { return 0 if (! -f $_[0]); return 0 if (! -r $_[0]); open FH, "<" . $_[0]; my $block = " " x 4096; my $bytesread = sysread FH, $block, 4096; close FH; if (! defined $bytesread) { print "*** ERROR: TextFile: $_[0]: $!\n"; return 0; } return $block =~ /^[\r\n\t -~]*$/s; }
    It attempts to guess whether a file is a text file based on what it sees in the first 4096 characters. I ran across it while seeking an alternative to -T to check for a text file. It seems to work in my tests, but I don't understand why because I don't understand what the regex is matching.

    My understanding is that [] defines a character class. A ^ before [] means negation. * means zero or more. $ means end of line. So if I put that all together, it seems to mean that
    $block =~ /^[\r\n\t -~]*$/s
    is true if $block does nor include any of \r\n\t -~ before an end of line. But that doesn't make sense. I'm also mystified by the inclusion of the characters -~ in the character class.

    Can anyone unpack all this for me?

    I am running strawberry perl 5.30 on windows 10.

    Thanks!
Bugfixing Old Code
2 direct replies — Read more / Contribute
by cluelessPerlMan
on Jul 22, 2021 at 11:27

    Dear Monks, I apologize I am completely clueless with Perl and as a favor have opted to help fix an old simulation model. The developer preceding me decided to use Perl to parse some data files, and for some reason it is no longer compiling and throwing errors. I am in the process of teaching myself Perl but any advice would be greatly appreciated. The errors being thrown: Experimental push on scalar is now forbidden at ../../plot_TTTDIA.pl line 44, near "@header)" Experimental push on scalar is now forbidden at ../../plot_TTTDIA.pl line 69, near "@twenty_SFs)" Execution of ../../plot_TTTDIA.pl aborted due to compilation errors.

    #!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser); use strict; use warnings; use feature 'say'; use List::Util 'max'; ## If the @left curve passes through the @right curve, ## replace the values that pass with 'nan'. sub trim_curves { my @left = @{shift @_}; # array of references my @right = @{shift @_}; my $rows = shift @_; # integer my $y = $rows - 1; # Start reading from the tail of the data first. for (my $i = $y; $i >= 1; $i--) { # $i = 0 is the header if (${$left[$i]} > ${$right[$y]}) { ${$left[$i]} = 'nan'; $y--; } else { # If @left is no longer greater, stop. last; } } return; } ## Grab useful information from the $infile and put it ## into a column-oriented, tab-separated format. sub parse_file { my $infile = shift @_; my $outfile = shift @_; open (my $in, '<', $infile) || die "Can't open $infile: $!"; open (my $out, '>', $outfile) || die "Can't open $outfile: $!"; # Build TTTPLOT data my @TTTPLOT; # 2D array my @header = ('Temperature', 'StartFerrite', 'StartPeralite', 'Sta +rtBainite', 'MaxSF'); for (my $i = 1; $i <= 20; $i++) { push @header, "SF($i)"; } push /@TTTPLOT, /@header; # Current row index of @TTTPLOT my $index = 1; # Index of 0 is the header above # Read the file's header data my $grade = <$in>; my $chemcomp = <$in>; my $grain = <$in>; my $asymptotes = <$in>; # Read the file's per-temperature data while(<$in>) { # Split on multiple spaces using regex captured matches my @temp_and_starts = $_ =~ /[^\s +]+/g; my @last_AT_fracs = <$in> =~ /[^\s +]+/g; my @twenty_SFs = (<$in> . <$in> . <$in> . <$in>) =~ /[^\s +]+/g; my $max_SF = max @twenty_SFs; # Build the @TTTPLOT row $TTTPLOT[$index]->[0] = $temp_and_starts[0]; $TTTPLOT[$index]->[1] = $temp_and_starts[1]; $TTTPLOT[$index]->[2] = $temp_and_starts[2]; $TTTPLOT[$index]->[3] = $temp_and_starts[3]; $TTTPLOT[$index]->[4] = $max_SF; push $TTTPLOT[$index], @twenty_SFs; $index++; } # Trim the overlapping tails off each combination of curves my @Fs = map \$_->[1], @TTTPLOT; # create an array of references my @Ps = map \$_->[2], @TTTPLOT; my @Bs = map \$_->[3], @TTTPLOT; trim_curves(\@Fs, \@Ps, $index); # check for ferrite greater than +pearlite trim_curves(\@Fs, \@Bs, $index); # check for ferrite greater than +bainite trim_curves(\@Ps, \@Bs, $index); # check for pearlite greater than + bainite # Output each row to the output file foreach my $row (@TTTPLOT) { say $out (join "\t", @{$row}); # tab-separated } close $in; close $out; return; } parse_file("./TTTPLOT.DAT", "./TTTPLOT_PARSED.DAT");

    This parsed file is never being generated obviously which is why none of the data is being graphed.

    Thank you to anyone who can provide some insight, I am sorry I have little to no experience working with Perl.
How do I import a global variable form a package with require?
1 direct reply — Read more / Contribute
by nysus
on Jul 22, 2021 at 09:47
    Monks, I was toying around with importing/requiring to improve my aptitude with them. So I have this package:
    #! /usr/bin/env perl package A; require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw (sub1 $var); our %EXPORT_TAGS = (all => [ qw(sub1 $var) ]); our $var = 7; sub sub1 { print "this\n"; } 1;

    I want to use require to import the $var global. I try this:

    #! /usr/bin/env perl use strict; use warnings; use lib '.'; require A; A->import (':all'); sub1(); print $var . "\n";

    This script throws Global symbol "$var" requires explicit package name (did you forget to declare "my $var"?).

    But I have no such error with Use A like so:

    #! /usr/bin/env perl use strict; use warnings; use lib '.'; use A ':all'; print $var . "\n";

    So I have a gap in my knowledge. I'm not sure why the second way works and the first doesn't. Any guidance is appreciated. Thanks!

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

Why is my Catalyst application creating a 'detach' file at the root level?
1 direct reply — Read more / Contribute
by LittleJack
on Jul 21, 2021 at 21:06

    While grepping through the code of a Catalyst app for c->detach() calls, I found that there was a file, simply called 'detach' at the top level.

    It contains log-file type entries, giving a module name and a line number plus an excerpt, and some of the lines relate to a call to the detach() method, but not all.

    I've tried googling and searching through CPAN for any hint about this file, but come up blank.

    TIA for any explanations monks may have. Is it a problem?

Can't get multiple Parallel::ForkManager threads connecting to DBD::Pg database
5 direct replies — Read more / Contribute
by perlygapes
on Jul 21, 2021 at 10:02
    Beloved Brewing Brethren Beholding Bitwise Borders,

    This follows on from my previous questions regarding Parallel::ForkManager and DBD::Pg.
    I have posted this to Stackoverflow, but haven't got a working answer...
    I am trying to create DB connections from multiple child threads, each of which is spawned as a child using Parallel::ForkManager.
    I cannot get this to work. I basically keep having the same sharing error - DBH cannot be shared between threads.

    Here is my example. I have included both a create_dbh and a clone_dbh sub-routine as options. Neither work.
    SQL TABLE SCRIPT:
    CREATE TABLE mytable ( field1 varchar(24) NULL, field2 varchar(24) NULL, field3 varchar(24) NULL, field4 varchar(24) NULL, field5 varchar(24) NULL, pk serial NOT NULL, CONSTRAINT mytable_pk PRIMARY KEY (pk) );
    PERL SCRIPT
    use 5.24.0; use strict; use warnings; use Parallel::ForkManager; use SQL::Abstract; use DBI ':sql_types'; use DBD::Pg qw/:pg_types/; #@codes = ("A"); # testing single thread my @codes = ("A","B","F","M","S"); # testing multi-thread my %varset; ################################################################ # connect to db ################################################################ my $dsn = 'DBI:Pg:dbname=$ENV{DB_NAME}'; my $userid = $ENV{DBI_USER}; my $sesame = $ENV{DBI_PASS}; my %dbh; # hash for storing dbh handles my $dbh = DBI->connect($dsn, $userid, $sesame, { AutoCommit => 1, RaiseError => 1, PrintError => 1 }) or die "Connection failed!\n" . $DBI::errstr; ################################################################ # test db connection ################################################################ my $me = $dbh->{Driver}{Name}; my $sversion = $dbh->{pg_server_version}; print "DBI is version $DBI::VERSION, " . "I am $me, " . "version of DBD::Pg is $DBD::Pg::VERSION, " . "server is $sversion\n"; print "Name: $dbh->{Name}\n"; ################################################################ # prepare array and hash for matching db columns ################################################################ my %columns; # hash for persistent mapping of column-values my @columns; # deterministic - $values[$columns{$column}]; set_columns(); # define column<->value mapping for db table my $placeholders = join(", ", map { '?' } @columns); ################################################################ # Build the SELECT SQL statement ################################################################ my $sql_select_statement = qq(SELECT count(*) FROM mytable WHERE id = ?;); ################################################################ # Build the INSERT SQL statement ################################################################ my $sql_insert_statement = "INSERT INTO mytable (" . join(", ", @columns) # column names . ") VALUES ($placeholders)"; ################################################################ # create clones of database handle and SQL statements for threads ################################################################ my %sth_select_code; my %sth_insert_code; #for my $code (@codes) { # $dbh{$code} = $dbh->clone(); # # prepare the SELECT statement handle # $sth_select_code{$code} = $dbh{$code}->prepare_cached($sql_select +_statement); # # prepare the INSERT statement handle # $sth_insert_code{$code} = $dbh{$code}->prepare_cached($sql_insert +_statement); #} ################################################################ # create Parallel::ForkManager object for @codes ################################################################ my $optimization = Parallel::ForkManager->new(scalar @codes); $optimization->run_on_start(sub{ my ($pid,$ident) = @_; print "Starting $ident under process id $pid\n"; }); $optimization->run_on_finish(sub{ my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_; }); my $thread_count = 0; OPTIMIZATION: for my $code (@codes) { $thread_count++; print "Thread $thread_count running for $code\n"; # fork optimization threads - per code $optimization->start($code) and next OPTIMIZATION; if ($code =~ m/A/i) { sub_a("A"); } elsif ($code =~ m/B/i) { sub_b("B"); } elsif ($code =~ m/F/i) { sub_f("F"); } elsif ($code =~ m/M/i) { sub_m("M"); } elsif ($code =~ m/S/i) { sub_s("S"); } print "\$optimization->finish on child $code\n"; $optimization->finish(0); } print "\$optimization->wait_all_children() is waiting...\n"; $optimization->wait_all_children(); ################################################################ # disconnect from database ################################################################ for my $code (@codes) { $sth_select_code{$code}->finish(); $sth_insert_code{$code}->finish(); $dbh{$code}->disconnect; } $dbh->disconnect; ################################################################ # end ################################################################ exit; ################################################################ sub sub_a { ################################################################ my $code = shift; # Code my @values; # clone_dbh($code); create_dbh($code); # my ($dbh, $sel_sth, $ins_sth) = create_dbh($code); # generate values specific to A $varset{field2} = 'a_f1'; # for illustrative purposes $varset{field3} = 'a_f2'; $varset{field4} = 'a_f3'; $varset{field5} = 'a_f4'; foreach my $key (keys %varset) { my $column = $key; # the column name as key my $value = $varset{$key}; # the column value (field variable +) $values[$columns{$column}] = $value; # add to list of column v +alues } $values[0] = $code; write_to_db($code, @values); } ################################################################ sub sub_b { ################################################################ my $code = shift; # Code my @values; # clone_dbh($code); create_dbh($code); # my ($dbh, $sel_sth, $ins_sth) = create_dbh($code); # generate values specific to B $varset{field2} = 'b_f1'; # for illustrative purposes $varset{field3} = 'b_f2'; $varset{field4} = 'b_f3'; $varset{field5} = 'b_f4'; foreach my $key (keys %varset) { my $column = $key; # the column name as key my $value = $varset{$key}; # the column value (field variable +) $values[$columns{$column}] = $value; # add to list of column v +alues } $values[0] = $code; write_to_db($code, @values); } ################################################################ sub sub_f { ################################################################ my $code = shift; # Code my @values; # clone_dbh($code); create_dbh($code); # my ($dbh, $sel_sth, $ins_sth) = create_dbh($code); # generate values specific to F $varset{field2} = 'f_f1'; # for illustrative purposes $varset{field3} = 'f_f2'; $varset{field4} = 'f_f3'; $varset{field5} = 'f_f4'; foreach my $key (keys %varset) { my $column = $key; # the column name as key my $value = $varset{$key}; # the column value (field variable +) $values[$columns{$column}] = $value; # add to list of column v +alues } $values[0] = $code; write_to_db($code, @values); } ################################################################ sub sub_m { ################################################################ my $code = shift; # Code my @values; # clone_dbh($code); create_dbh($code); # my ($dbh, $sel_sth, $ins_sth) = create_dbh($code); # generate values specific to M $varset{field2} = 'm_f1'; # for illustrative purposes $varset{field3} = 'm_f2'; $varset{field4} = 'm_f3'; $varset{field5} = 'm_f4'; foreach my $key (keys %varset) { my $column = $key; # the column name as key my $value = $varset{$key}; # the column value (field variable +) $values[$columns{$column}] = $value; # add to list of column v +alues } $values[0] = $code; write_to_db($code, @values); } ################################################################ sub sub_s { ################################################################ my $code = shift; # Code my @values; # clone_dbh($code); create_dbh($code); # my ($dbh, $sel_sth, $ins_sth) = create_dbh($code); # generate values specific to S $varset{field2} = 's_f1'; # for illustrative purposes $varset{field3} = 's_f2'; $varset{field4} = 's_f3'; $varset{field5} = 's_f4'; foreach my $key (keys %varset) { my $column = $key; # the column name as key my $value = $varset{$key}; # the column value (field variable +) $values[$columns{$column}] = $value; # add to list of column v +alues } $values[0] = $code; write_to_db($code, @values); } ################################################################ sub create_dbh { ################################################################ my $code = shift; $dbh{$code} = DBI->connect($dsn, $userid, $sesame, { AutoCommit => 1, RaiseError => 1, PrintError => 1 }) or die "Connection failed!\n" . $DBI::errstr; # did it work? are we there yet? my $me = $dbh{$code}->{Driver}{Name}; my $sversion = $dbh{$code}->{pg_server_version}; print "DBI is version $DBI::VERSION, " . "I am $me, " . "version of DBD::Pg is $DBD::Pg::VERSION, " . "server is $sversion\n"; print "Name: $dbh->{Name}\n"; # prepare the SELECT statement handle $sth_select_code{$code} = $dbh{$code}->prepare_cached($sql_select_ +statement); # prepare the INSERT statement handle $sth_insert_code{$code} = $dbh{$code}->prepare_cached($sql_insert_ +statement); } ################################################################ sub clone_dbh { ################################################################ my $code = shift; $dbh{$code} = $dbh->clone(); # prepare the SELECT statement handle $sth_select_code{$code} = $dbh{$code}->prepare_cached($sql_select_ +statement); # prepare the INSERT statement handle $sth_insert_code{$code} = $dbh{$code}->prepare_cached($sql_insert_ +statement); } ################################################################ sub write_to_db { ################################################################ my ($code, @values) = shift @_; my $rv_code = $sth_select_code{$code}->execute($code); if($rv_code < 0) { print $DBI::errstr; } my @row = $sth_select_code{$code}->fetchrow_array(); # if the SELECT found no existing records for this strategy, then +INSERT it unless ($row[0] > 0) { # INSERT settings into 'mytable' $sth_insert_code{$code}->execute(@values); } } ################################################################ sub set_columns { ################################################################ $columns{field1} = 0; $columns{field2} = 1; $columns{field3} = 2; $columns{field4} = 3; $columns{field5} = 4; $columns[0] = 'field1'; $columns[1] = 'field2'; $columns[2] = 'field3'; $columns[3] = 'field4'; $columns[4] = 'field5'; }
    Do I have to pass dbh and statement handles to the create_dbh sub explicitly from within the calling sub_x thread?
    Do I have to return the handles or handle_refs from create_dbh back to calling sub_x thread?
    I don't know how to get around this, but it seems like a lexical scope or object/memory access issue.

    Any advice?
Cookie not signed after upgrading mojolicious
1 direct reply — Read more / Contribute
by newperldeveloper
on Jul 21, 2021 at 06:40
    I have two applications one to view the data and an old application(cgi) that is downloading the data. After upgrading the mojolicious to version 9.30 the cgi application uses the following code.
    builder { enable 'Session', store => Plack::Session::Store::File::Mojolicious +->new($ENV{directory} ? (dir => $ENV{directory}) : ()), state => Plac +k::Session::State::Cookie::Mojolicious->new(secure => 1, session_key +=> 'download_app'); $app; };
    After the upgrade i am getting the following error message in the log Cookie "download_app" is not signed. After adding secret=>'my secret' I am still getting the same error. I am taking over for someone and I believe the code is acting as a wrapper for mojolicious that lets you login to the viewing app code. Downgrading Mojolicious removes the error. And if i login to cgi app i have access to the viewing app and vice versa.
Plaintext plot - existing sofware?
5 direct replies — Read more / Contribute
by parv
on Jul 21, 2021 at 04:10

    Before I write a program to chart x-y values in plain text (again), does anyone know of any software|code to share which would spit out "scatter plot" on standard output (or in a file) in plain text (no image-graphs, Excel, LibreOffice, etc)?

    I could not find something relevant here ("text plot"); on MetaCPAN; via DuckDuckGo.


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