Is there an elegant way to return out of a module early? I like the style in subs of something like return unless $arg and wanted something similar in packages/modules. I know I can put all the logic in subs and conditionally call the subs, but TMTOWTDI. This seems to work but is ugly: BEGIN { local $SIG{__DIE__}; die if $check }.
|
Hello Monks!
I'm writing mod-perl handler scripts to run on Apache 2.4 under Ubuntu 24.04. I'm using mod_authnz_ldap to connect to an Active Directory for authentication and authorization. mod_authnz_ldap relies on mod-ldap and the docs for mod-ldap only discuss it providing LDAP services to other modules.
My handler script needs to make several LDAP queries and I would like to take advantage of mod-ldap's persistent connections and operation cache.
Is this possible? It's very hard to find relevant documentation on the web because of the huge number of search results regarding authentication, authorization, Net::LDAP and, of course, Apache's own Directory Server software. Can anyone point me at relevant material or give me some hints?
Yours,
<°}}}>«<
|
I would love if there was an official reference listing features and backcompat alternatives.
So far, I've only found these:
Can you think of any others?
|
Hello, Monks!
I come seeking your wisdom once more. Today, the question that I have is a simple matter of loops and how they work when they happen within functions such as grep.
This is my code:
for my $component ( split(/,/, $components_csv) ) {
if (grep { $_ eq $component } @url_components) {
push( @selected_components, $component);
next;
}
# ...
}
In this example, the next keyword: would take me to the next iteration of grep, or to the next iteration of the outer for loop? I could use a label to handle this, but I'm not sure if I need to.
Thank you, cheers.
|
As usual, this is about Someone Else's Code. Not in a blamey way, just that it seems to be my thing to trip over odd cases and bring them out for scrutiny by the good monks. Today I was successful in installing a module published by our good monk cavac, the CPAN module Array::Contains to a Gnu/Linux system, then a few minutes later I went to install it to my cygwin perl setup. I get an error that takes some scrunching up of one's eyes to figure out.
Simplest test case is a one-liner:
$ perl '-Mdiagnostics' -le 'print $diagnostics::VERSION'
couldn't find diagnostic data in /usr/share/perl5/5.40/pods/perldiag.p
+od /usr/share/perl5 /usr/local/lib/perl5/site_perl/5.40/x86_64-cygwin
+-threads /usr/local/share/perl5/site_perl/5.40 /usr/lib/perl5/vendor_
+perl/5.40/x86_64-cygwin-threads /usr/share/perl5/vendor_perl/5.40 /us
+r/lib/perl5/5.40/x86_64-cygwin-threads /usr/share/perl5/5.40 -e at /u
+sr/share/perl5/5.40/diagnostics.pm line 259, <POD_DIAG> line 718.
Compilation failed in require.
BEGIN failed--compilation aborted.
The first 10 lines of Array::Contains are:
package Array::Contains;
use 5.010_001;
use strict;
use warnings;
use diagnostics;
use mro 'c3';
use English;
our $VERSION = 2.8;
use Carp;
I don't see many modules that use diagnostics so this hasn't come up before for me.
Apr 16, 2025 at 02:05 UTC
A just machine to make big decisions
Programmed by fellows (and gals) with compassion and vision
We'll be clean when their work is done
We'll be eternally free yes, and eternally young
Donald Fagen —> I.G.Y.
(Slightly modified for inclusiveness)
|
For several years now, I've used a home made RSS reader to collect and deal with my podcasts. You can see the full code here: github.
I just moved it to a new computer (Ubuntu 24.04, perl 5.38.2; the previous one was Ubuntu 22.04, perl 5.30.0) and suddenly it's failing to be interpret the RSS feeds that are working fine on the old machine.
It's failing on line 277, where it runs parse_string(), which is returning undef instead of the RSS object I get on the old machine, and I cannot work out what might be different to cause this. Any help would be gratefully appreciated.
|
Dear Monkees
I want to replace a string with another string which contains (lots of) @, [, ( etc. which have special meaning in Perl and definetely I don't want them to be interpolated.
I can use the q{} function to quote these but how can I call it inside the regular expression, e.g. $xx =~ s/<%xpath%>/\Qq{//div[@id="abc"]}\E/e (does not recognize q{}).
bw, bliako
|
Greetings monks,
It's late, I'm tired, and I must be missing the obvious. I need another pair of eyes to see what I've overlooked. The code sample below tests a file name against a regex containing the same file name. The first test uses forward slashes (and works as expected). The second test uses backslashes and does not work.
Please note: I have tried escaping the backslashes, but it still fails. I have tried running the regex through the "qr()" function, but it still fails. What am I missing here? TIA for any help you can provide.
#!/usr/bin/perl
use strict;
use warnings;
# WORKS
my $file = 'C:/tmp';
my $regex = 'C:/tmp';
if ($file =~ m/$regex/i) {
print "\nTest with forward slashes -- If stmt is true...\n";
}
# FAILS
$file = 'C:\tmp';
$regex = 'C:\tmp';
if ($file =~ m/$regex/i) {
print "\nTest with backslashes -- If stmt is true...\n";
}
"It's not how hard you work, it's how much you get done."
|
Esteemed Monks (especially the W::M::C one!)
I am not able to find elements in the DOM which are injected dynamically (e.g. via javascript after page load)
These fail: wait_until_visible(xpath=>...) and xpath('...').
<!-- save me as ./content.html -->
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<div id='id1'>element in html</div>
<div id='dynamic-container'></div>
<script>
document.addEventListener("DOMContentLoaded", function(){
setTimeout(function(){
var anElem = document.createElement('span');
anElem.setAttribute("id", "id2");
anElem.innerHTML = "appearing after 1.5s";
document.getElementById('dynamic-container').appendChild(anEle
+m)
},1500);
setTimeout(function(){
var dyn = document.getElementById('id2');
var str = "The dynamic element was "+(dyn==null?"NOT":"")+" fo
+und by getElementById()";
alert(str);
console.log(str);
},2000);
}); // on dom loaded
</script>
</body>
</html>
# it assumes a ./content.html is present on same dir
#!/usr/bin/env perl
use strict;
use warnings;
use WWW::Mechanize::Chrome;
use Log::Log4perl qw(:easy);
use FindBin;
Log::Log4perl->easy_init($ERROR);
my %mech_params = (
headless => 0,
launch_arg => [
'--window-size=600x800',
'--password-store=basic', # do not ask me for stupid chrome ac
+count password
# '--remote-debugging-port=9223',
# '--enable-logging', # see also log above
'--disable-gpu',
'--no-sandbox',
'--ignore-certificate-errors',
'--disable-background-networking',
'--disable-client-side-phishing-detection',
'--disable-component-update',
'--disable-hang-monitor',
'--disable-save-password-bubble',
'--disable-default-apps',
'--disable-infobars',
'--disable-popup-blocking',
],
);
my $mech = WWW::Mechanize::Chrome->new(%mech_params);
$mech->get('file://'.$FindBin::Bin.'/content.html');
my $elem;
$elem = eval { $mech->xpath('//div[@id="id1"]', single=>1) };
die "non-dynamic element not found" unless defined $elem;
$mech->sleep(2);
my $ret = eval { $mech->wait_until_visible(
xpath=>'//div[@id="id2"]',
timeout=>2, # it's already there after 1.5s
); 1;
};
die "dynamic element not found"
unless defined($ret) && ($ret==1) && ! $@;
print "OK dynamic element found!\n";
What I am trying to do is to get notified when a page has finally loaded and settled and when all sort of dynamic HTML elements have been loaded, long after a "DOM-ready" event was fired.
Javascript's getElementById() succeeds. Do I have to poll myself with javascript eval()?
Edit:
I have solved this by following ++LanX's suggestion which is to search/poll HTML elements via javascript. So I am now using something like: do { ($ret, $typ) = $mech->eval($js) } while($ret==0 && !$timeout && $mech->sleep(0.5));. Where $js could be something like this which returns the number of items matched by the specified XPath selector:
document.evaluate('//div[@id="abc"]', null, document.body, null, XPath
+Result.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength;
Thank you Corion for WWW::Mechanize::Chrome
thank you
bw, bliako
|
Even though I am pretty good at Perl regex, I am learning Perl regex so I can understand the Perl Monks threads on the subject.
I found https://perldoc.perl.org/perlretut entitled perlretut - Perl regular expressions tutorial.
Everything was fine until I came upon this passage in https://perldoc.perl.org/perlretut#Using-character-classes.
(This is a tutorial. It probably belongs in a footnote.)
For natural language processing (so that, for example, apostrophes are
+ included in words), use instead \b{wb}</p>
"don't" =~ / .+? \b{wb} /x; # matches the whole string
What is going on here?
Regex101 is no help.
I wrote a test to try to understand it. It only caused me more confusion.
use warnings;
use strict;
use feature qw{ say };
if ("don't" =~ / (.+?) (\b{wb}) /x) { # matches the whole string
print "It matches\n";
say $1;
say $2;
}
else {
print "It doesn't match\n";
}
if ("don't" =~ / (.+?) /x) { # It no longer matches the whole string
print "It matches\n";
say $1;
}
else {
print "It doesn't match\n";
}
Output:
It matches
don't
It matches
d
Who is going to attempt natural language processing with a couple of lines of Perl regex in 2025?
|