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
detecting an undefined variable
3 direct replies — Read more / Contribute
by LloydRice
on Sep 21, 2019 at 08:41

    How do I detect whether a variable has been defined in an enclosing context? I tried

    my $myscale = 1; if ( defined $scale ) { $myscale = $scale; }
    When $scale does not exist in the outer context, this fails. So then I tried
    my $myscale = $scale // 1;
    with the same result. But "defined" seems to want an existing object (function, array, etc.), So finally, I tried it this way ..
    my $myscale = extscale // 1; sub extscale { return $scale; }
    I have reread the Camel sections on "defined" and "exists". Neither of these does what I am looking for. Is there some way to do this?

DBI: select distinct returns same values
2 direct replies — Read more / Contribute
by tukusejssirs
on Sep 21, 2019 at 06:45

    I have strange problem.

    I have Pg database table with 20,000+ rows. The only important column from this table is the timestamp column called date.

    I need to get all unique dates from the table, so I run the following code in the terminal:

    mydb=# select distinct cast(date as date) from myschema.mytable; -[ RECORD 1 ]----------- date | 2019-09-18 -[ RECORD 2 ]----------- date | 2019-09-20 -[ RECORD 3 ]----------- date | 2019-09-19

    which is correct. However, when I run the following code, it output three times the same date:

    $sth_dates_uniq = $dbh->prepare("select distinct cast(date as date) fr +om myschema.mytable;") or die; $sth_dates_uniq->execute(); my @all_rows; while ( my $ref = $sth_dates_uniq->fetchrow_arrayref()) { push(@all_rows, $ref); } foreach my $row_ref (@all_rows) { print "@{$row_ref}\n"; } # Output 2019-09-19 2019-09-19 2019-09-19

    Do I do something wrong or is this a bug? What else could I do? I could get all the data from the table, sort them and get all unique values, however, the table is quite big to do so. Id like to have it as fast as possible.

Imports with Module::Load::Conditional
1 direct reply — Read more / Contribute
by Anonymous Monk
on Sep 20, 2019 at 09:31
    #!/usr/bin/perl # # SOPW: How does one import things # with Module::Load::Conditional? # # Like: # use IPC::Cmd 'QUOTE'; # use Time::HiRes 'time'; # print join '', QUOTE, time, QUOTE, "\n"; # # So they don't have to be fully qualified for use # like Time::HiRes::time() (<- parens not optional) use 5.9.5; use strict; use warnings; use Module::Load::Conditional 'can_load'; my $modules = { map {$_ => undef} qw/ IPC::Cmd Time::HiRes /}; die "Please install required perl modules: \n". join ' ', 'cpan', keys(%$modules), "\n". join ' ', 'cpanm -v', keys(%$modules), "\n" unless can_load(modules=>$modules, autoload=>1); print join '', IPC::Cmd::QUOTE(), Time::HiRes::time(), IPC::Cmd::QUOTE(),"\n"; #print join '', QUOTE, time, QUOTE, "\n"; # goal
Restarting a Perl script on Windows 10
4 direct replies — Read more / Contribute
by petro4213
on Sep 20, 2019 at 06:06
    I have a Perl script with a GUI that restarts itself, if I press a button in the GUI. This is done through this simple call in the callback of the button:
    exec( $pathToMyself );
    This works fine on Windows 7. But on Windows 10, the script ends (and the GUI disappears), but it doesn't restart, unless I go to the command window, which I used to initially call the script, and press the Enter key there.
    I don't like this behavior. Can anyone explain, where this comes from or give me a hint, if there's something I can do from the Perl side to restart my script without having to press Enter?
    Thanks a lot!

    Here's a simple reproducible example:

    use Tk; use strict; my $pathToMyself = $0; my $mw = MainWindow->new(); my $bt = $mw->Button(-text=>"Restart", -command=>\&restartMe)->pack(); MainLoop; sub restartMe { print "Restarting $pathToMyself...\n"; exec( $pathToMyself ); }
Module name case typo silent failure
3 direct replies — Read more / Contribute
by Anonymous Monk
on Sep 19, 2019 at 15:05
    From time to time I forget to camelcase "HiRes" and this happens:
    
    perl -MTime::Hires=time -Wle 'print time'
    1568918270
    
    
    Of course it should be:
    
    perl -MTime::HiRes=time -Wle 'print time'
    1568918268.29395
    
    
    Questions:

    Why no warning for module name camelcase typos?
    Why no warning for the failed import of time function from bogus module?

    Same in scripts with strict and warnings...

Re-uploading the previous non-trial version of a distribution to CPAN
3 direct replies — Read more / Contribute
by stevieb
on Sep 19, 2019 at 12:09

    Hello all,

    I have recently come across an issue in my RPi::WiringPi distribution (version 2.3632). Somehow, through all of the testing I do before I create a release, I missed an issue in a test file which breaks installation.

    Now, since then, I've made dozens of updates in my repository across two new trial versions (2.3633_01, which is released to CPAN, and 2.3633_02, which hasn't been uploaded). Is there an effective, safe way that I can fix this issue in a branch based off of the release commit and re-publish it as 2.3632, which is the current valid version which is installed via cpan/cpanm?

    I'd rather not have my VCS logs all out of whack and having to change Changes and other things if possible. In PAUSE, under the Utils menu, I came across a "Reset Version" option which looks like it'll do what I want, but I've never used this feature and am hoping that there's someone here has, and can provide some guidance.

    Thanks,

    -stevieb

Mojolicious, apache reverse proxy
4 direct replies — Read more / Contribute
by slatibart
on Sep 19, 2019 at 09:51
    Hi,

    I have apache running and need to run a mojolicious app under the path /rules

    This is the apache config part

    ProxyRequests Off ProxyPreserveHost On ProxyPass /rules http://localhost:3000/ keepalive=On ProxyPassReverse /rules http://localhost:3000/ RequestHeader set X-Forwarded-HTTPS "0"
    Very simply mojolicious script with a route to / and a route to /user
    app->hook(before_dispatch => sub { my ( $c ) = @_; my $url = $c->req->url; my $base = $url->base;# push @{ $base->path }, 'rules'; $base->path->trailing_slash(1); $url->path->leading_slash(0); }); get '/' => sub { my $self = shift; my $host = $self->tx->remote_address; my $content = "Host: $host"; $self->stash(content=>$content); $self->render('index'); }; get '/user' => sub { my $self = shift; my $host = $self->tx->remote_address; my $content = "Host: $host"; $self->stash(content=>$content); $self->render('index'); }; app->start; __DATA__ @@ index.html.ep % layout 'default'; <%== $content %> @@ layouts/default.html.ep <!DOCTYPE html> <html lang="en"> <head> <title>Test</title> </head> <body> %= button_to Home => '/' %= button_to User => '/user' %= link_to Home => '/' %= link_to User => 'user' %= content </body> </html>
    Generated html looks good.
    <!DOCTYPE html> <html lang="en"> <head> <title>Test</title> </head> <body> <form action="/rules"><input type="submit" value="Home"></form> <form action="/rules/user"><input type="submit" value="User"></form> <a href="/rules">Home</a> <a href="/rules/user">User</a> Host: 127.0.0.1 </body> </html>
    Using the home button / links works but for route /user mojolicous throws an error.

    "None of these routes could generate a response for your GET request for //user, maybe you need to add a new one?"

    Where is that extra slash coming from and how to get rid of that ?

    Bonus question. If I add another layer   push @{ $base->path }, 'all/rules'; all slashes are transformed.

    <form action="/all%2Frules"><input type="submit" value="Home"></form> <form action="/all%2Frules/user"><input type="submit" value="User"></f +orm> <a href="/all%2Frules">Home</a> <a href="/all%2Frules/user">User</a>
    Any idea why ?

    Thanks for your help.

Adding cols to 3d arrays - syntax
6 direct replies — Read more / Contribute
by peterrowse
on Sep 19, 2019 at 07:44
    Dear monks, I am having difficulty refreshing myself on referencing multidimensional arrays, I am sure I knew this before but it eludes me now. Whether my approach to this is just nonsense or whether its OK but my referencing is wrong I am not sure but I am pretty sure I have done this in the past. My code is this:
    use strict; my @myarr; my $lpn; my $ppn; my $i; for ($i=0;$i<15;$i++) { ($lpn, $ppn) = get_ns($i); push @{ $myarr[$lpn] }, $ppn; } for my $index (0..$#myarr) { next unless defined $myarr[$index]; my @tmp; for my $subindex (0..scalar(@{$myarr[$index]})-1) { my $date; for ($date=0;$date<10;$date++) { $tmp[$date] = get_date($index, $subindex); } push @{$myarr[$index][$subindex]}, [ @tmp ]; } } sub get_ns { return (int(rand(100)), int(rand(100))); } sub get_date { return get_ns; }
    I get
    Can't use string ("23") as an ARRAY ref while "strict refs" in use at +./eg.pl line 24.
    when I try to run it, and my line
    push @{$myarr[$index][$subindex]}, [ @tmp ];

    seems to be the problem - I've tried all the variations on syntax I can remember trying to hit on the correct one and searched perlmonks for similar questions but I can't find examples with 3 levels of array and moving from 2 to 3 seems to be my problem. However perhaps I am not seeing that somewhere I am making a mistake higher up and that I am indeed referencing it right but not stuffing the right values and hence causing the error, I am not sure.

    If anyone can point out my error it would be hugely appreciated.

    Pete

Update Primary Key with DBIx::Class
3 direct replies — Read more / Contribute
by phildeman
on Sep 18, 2019 at 15:43

    Hi

    I was attempting to update a MySQL table's primary key using DBIx::Class. I do not get any errors executing the update.
    However, when I check the table using Workbench or MySQL Client, it shows the old value.

    Is DBIx::Class restricted from updating primary keys. It can be done with DBI.

    Here is a snippet of code to perform the update:

    use My::Data; my $schema = "My::Data"; my $acct = $schema->resultset( 'Accounts')->search({ acctid => 'pv001' + })->single; if($acct) { $acct->acctid( 'pv002' ); $acct->update; } else { print "Could not find account to update!\n\n"; }

    As I stated, when I check the table, the value 'pv001' is still in the database. I searched for 'pv002', I could not find any record
    with that value as the primary key.

    Has anyone encounter this issue where DBIx::Class will not update the primary key? If yes, how did you resolve this issue?
    I am hoping there is a resolution, before I use DBI.

    Thanks.

    -Phil-

Global symbol "$prepare" requires explicit package name
1 direct reply — Read more / Contribute
by tukusejssirs
on Sep 18, 2019 at 15:42

    I have a table filled with some data; the only important for this question is date.

    Now I need to update (modify) the date column (which contains timestamp formatted like this: YYYY-MM-DD HH:MM:SS+ZZ so that the date portion will become today (or possibly any other date) while the time portion remains intact. It should take into account the daylight saving.

    But I ran into some problems. While I was trying to deal with it, there where different errors:

    DBD::Pg::st execute failed: execute called with an unbound placeholder + at ./refresh_dates.pl line nn. DBD::Pg::st execute failed: execute called with an unbound placeholder + at ./refresh_dates.pl line nn. # Or: Can't locate object method "execute" via package "DBI::db" at ./refres +h_dates.pl line nn.

    Current error looks like this:

    Global symbol "$prepare" requires explicit package name at ./refresh_d +ates.pl line nn. Execution of ./refresh_dates.pl aborted due to compilation errors.
    All of these errors were about the same line(s), these:
    my $sth2 = $dbh->$prepare("update $schema.$table set $date_col = $date +_new where $where_col = 1;") or die; $sth2->execute();
    And here is the current code in full. Note that I plan to implement a for, but for now I just wanted to test the code with one (first) row.
    #!/bin/perl use strict; use warnings; use lib ('./'); use mylib; use DateTime; use DateTime::Duration; use Time::Piece; use POSIX qw(strftime); # User-dependent variables my $db_driver = 'Pg'; # `Pg` for psql, `mysql` for +mysql my $username = 'postgres'; # Database user name my $password = 'password'; # Database user password my $database = 'mydb'; # Database name my $schema_table = 'myschema.mytable'; # Schema.table # Other variables my $schema = $schema_table; my $table = $schema_table; $schema =~ s/^([^.]*).*$/$1/; $table =~ s/^[^.]*.([^.]*)$/$1/; if ($schema_table =~ /\./){ $schema =~ s/^([^.]*).*$/$1/; $table =~ s/^[^.]*\.([^.]*)$/$1/; } else { $schema = 'public'; $table = $schema_table; $schema_table = '$schema.$table'; } my $date_col = "date"; my $where_col = "id"; my ($hours, $minutes, $seconds); my (@date_time, $temp, $date_new); my ($year, $month, $day); my ($date_tbl, time_tbl); my ($dsn, $dbh, $sth, $sth2); # Open the database $dsn = "DBI:$db_driver:dbname = $database"; $dbh = DBI->connect($dsn, $user, $password, { RaiseError => 1 }) or di +e RED, "ERROR: The database could not be opened.\n $DBI::errstr +\n Stopped$!"; print "INFO: The database has been opened successfully.\n"; # Get time from DB $sth = $dbh->prepare("select $date_col from $schema.$table where $wher +e_col = 1;") or die; $sth->execute(); $sth->bind_col(1, \$temp); while ($sth->fetch()) { $date_time[0] = $temp; } # Get date $date_tbl = $temp; $temp =~ /([^-]+)-([^-]+)-([^-]+) /; ($year, $month, $day) = ($1, $2, $3); # Get hours, minutes, seconds from time $time_tbl = $temp; $time_tbl =~ / ([^:]+):([^:]+):([^:]+)[+]/; ($hours, $minutes, $seconds) = ($1, $2, $3); # Set new date $date_new = DateTime->today->set_time_zone('Europe/London')->set_hour( +$hours)->set_minute($minutes)->set_second($seconds)->strftime("%F %T% +z"); # Update the dates $sth2 = $dbh->$prepare("update $schema.$table set $date_col = $date_ne +w where $where_col = 1;") or die; $sth2->execute(); # Close the database $dbh->disconnect() or die RED, "ERROR: The database could not be disco +nnected.\n $DBI::errstr\n Stopped$!";

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.