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.
I receive such json file as input. As you can see it is an array of objects where each object is an array of sub-objects. Brief it is a collection of nested objects and arrays.
I don't know in advance the structure, the name of the keys and the levels of nesting. Or even it can also be the other way around, a collection of objects with arrays nested on it.
The only thing I should know is the object identifier "key name" found at level 2 (in my example "Obj11Id", "Obj12Id", etc).
My goal is for each pair of key name and value, to have the "full path" of the key name and the key value. By "full path" I understand the name of the above keys in the structure.
Example: for the pair "Obj11AttributesObj1Key1": "1", the "full path" would be: "Obj1.Obj11Attributes.Obj11AttributesObj1.Obj11AttributesObj1Key1" (dot "." being the separator of the above keys).
I'm new in Perl, I've tried many ways to obtain this info but failed. I'm using the library JSON::PP and function decode_json.
I am posting a success instead of a failure, for a change ;-). In brief, I've
patched the test file for Win32::Netsh so that the Wlan instance tests no
longer fail (on a recent Windows release). I first wrote a short subroutine which
I'll submit here for comments and critiques:
#!/usr/bin/env perl
use strict;
use v5.18;
use utf8;
use warnings;
use Carp qw/carp croak/;
=head1 DESCRIPTION
Find the major Windows version from the commandline "ver" command.
=cut
# ------------------------------------------------------- #
# Example Windows 11 version string (bought the machine
# with Windows 10 loaded on it):
# Microsoft Windows [Version 10.0.26100.4349]
# ------------------------------------------------------- #
sub findVer
{
my ( $which , $verstr );
$verstr = `ver`;
chomp $verstr;
$verstr =~s{\A\n}{};
$verstr =~m'\[Version\s (\d+) [.]'x;
carp( qq/Couldn't get version from string "$verstr"/ ) unless $1;
$which = $1;
return $which;
}
say findVer();
__END__
The reason it matters to Win32::Netsh is that at some vague point in time (Google AI
doesn't know exactly when), M$ stopped calling a wireless interface a "Wireless
Network Connection" and started calling it a "Wi-Fi". This broke the Win32::Netsh test
suite file 02-Win32-Netsh-Wlan.t for my machine. Here's the patch (Unified diff
format, line endings converted to UNIX). I'd be very
interested in hearing from other Windows Perlers how this patch works on their version
of Windows (I'm going to test it on Windows7):
--- a/t/02-Win32-Netsh-Wlan.t 2015-11-17 16:07:55.000000000 -0500
+++ b/t/02-Win32-Netsh-Wlan.t 2025-06-18 14:52:56.388437700 -0400
@@ -26,36 +26,61 @@
);
}
use_ok(qq{Win32::Netsh::Wlan}, (qw(:all)));
}
+##---------------------------------------
+## Find Windows Version
+
+# ------------------------------------------------------- #
+# Example Windows 11? or 10? version string:
+# Microsoft Windows [Version 10.0.26100.4349]
+# ------------------------------------------------------- #
+sub findVer
+{
+ my ( $which , $verstr );
+ $verstr = `ver`;
+ chomp $verstr;
+ $verstr =~s{\A\n}{};
+ $verstr =~m'\[Version\s (\d+) [.]'x;
+ carp( qq/Couldn't get Windows version from string "$verstr"/ ) un
+less $1;
+ $which = $1;
+ # say "VERSION: " . $which;
+ return $which;
+}
+
+my $generation = findVer();
##---------------------------------------
## List of profiles to use for testing
##---------------------------------------
my @test_profiles = (
{ filename => qq{win32-netsh-wlan-single.xml},
info => {
name => qq{Win32-Netsh-Wlan-Single},
auth => qq{Open},
cipher => qq{None},
- interface => qq{Wireless Network Connection},
+ interface => ( $generation >= 10 ?
+ qq{Wi-Fi}
+ : qq{Wireless Network Connection} ),
mode => qq{automatical},
net_type => qq{Infrastructure},
radio => qq{[ Any Radio Type ]},
ssid => [qq{SSID-Single}],
},
},
{
filename => qq{win32-netsh-wlan-dual.xml},
info => {
name => qq{Win32-Netsh-Wlan-Dual},
auth => qq{Open},
cipher => qq{None},
- interface => qq{Wireless Network Connection},
+ interface => ( $generation >= 10 ?
+ qq{Wi-Fi}
+ : qq{Wireless Network Connection} ),
mode => qq{automatical},
net_type => qq{Infrastructure},
radio => qq{[ Any Radio Type ]},
ssid => [
qq{SSID-Dual-01},
qq{SSID-Dual-02}
I'm having trouble installing the Readonly module to StrawberryPerl
apparently because it uses Module::Install::TinyModule::Build::Tiny as its build / test / install
infrastructure. I haven't been aware that I was running that build module before
now, but obviously if nothing goes wrong the build system should be in the background
just Doing The Right Thing™. So I won't have noticed.
I'm running a StrawberryPerl managed as an instance of Perl 5.40.2 by berrybrew.
I feel like I have to show my fellow monks that I don't have a crazy setup, after
some of my recent misadventures. Here's my %PATH% (speaking the CMD.exe dialect
since we're talking about Windows):
I know, it looks like I am running cygwin, but believe me, I have the right Perl and
tools. The above is prettified output of a (perl) script I wrote to manage my PATH.
I'm an EU::MM guy, I love make, and this just baffles me. I'm not trying to find someone to blame (no profit in that), but I would like to spend less time debugging the build of a simple module.
EDIT
Struck out imaginary module Module::Install::Tiny, in first paragraph above.
Jun 16, 2025 at 18:47 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)
I have tried to download the 8mb index.all file from the Gutenburg Project website with LWP::UserAgent but it only gets around 5mb.
With wget I gets the full file, is there some limit in LWP? I have tried LWP::Agent many times and it gets between 4mb-5.2mb.
my $url = 'https://www.gutenberg.org/dirs/GUTINDEX.ALL';
my $file = '/home/philip/APPLICATIONS/GUTINDEX.ALL';
say $url;
my $browser = LWP::UserAgent->new();
my $response = $browser->get($url);
open my $fp,">",$file || die "Error saving book $!\n";
print $fp $response->content();
close $fp;
I visited the Rosetta Code, for solution to a problem in a language, which both don't matter here; then checked Perl solution there; then, out of idle curiosity, as it's usual with time wasting e.g. browsing dictionaries, clicked for one more task; and -- I swear (and don't know what in its title attracted me)-- at exactly the 3d task I found a Perl solution:
Out of ALL contestants, the task was misread to include 5-letter words, and even then, the algorithm is broken as it doesn't contain e.g. "crises crisis" pair, etc. So sad :-(. Village idiot, our Perl, no less. No, I don't have editing rights there, nor did I find in page's history how/when it was added.
However, I've been surprised to find it hard and not obvious (to me), how to match the solution's speed/memory. Presumably, if corrected they'd stay the same or close. My initial attempts with e.g. grep/map/split/regexes or what not -- they all were worse.
Finally, here's my solution (under Strawberry):
use strict;
use warnings;
sub memory { qx( tasklist /nh /fi "PID eq $$" ) =~ m[(\S+ K)$] }
use Time::HiRes 'time';
my $t = time;
my ( @a, %h );
open my $fh, '<:raw', 'unixdict.txt' or die;
while ( <$fh> ) {
next unless length > 6;
chomp;
( -1 != index $_, 'e' ) ? ( push @a, $_ ) :
( -1 != index $_, 'i' ) ? ( $h{ $_ } = 1 ) : 1
}
close $fh;
my ( $s, $i ) = '';
exists $h{ $i = tr/e/i/r }
and $s .= sprintf "%30s %s\n", $_, $i
for @a;
print time - $t, "\n";
print memory, "\n";
print $s;
It's on average "0.018 s, 10,100 K" vs "0.033 s, 11,100 K" of similarly modified (but still unfixed) original. Not that "performance" matters for the task, how ever ridiculous this achievement is.
I'm trying to optimize a regex using the SKIP and MARK verbs, and not understanding how they should be properly used together. Sadly, the documentation provides no examples, and doesn't seem to rigorously define its terms:
"(*MARK:*NAME*)" "(*:*NAME*)"
This zero-width pattern can be used to mark the point reached in
a string when a certain part of the pattern has been successfully
matched. This mark may be given a name. A later "(*SKIP)" pattern
will then skip forward to that point if backtracked into on
failure.
to capture the b, yet it again captures the second a.
Perhaps subpatterns such as (?!...) don't share marks with the main pattern? The slightly more verbose pcre doc seems to say that. But then this should work:
I've been installing packages via cpan without any problems. Then I had some failures with Perl using the wrong compiler command and options, so I corrected that, got out of cpan and then back in. Ever since I got back in, nothing will install now. I keep getting the following error for everything:
gpg run was failing, cannot continue: "/opt/freeware/bin/gpg" --verify
+ --batch --no-tty --output "/tmp/CHECKSUMS-eMRO/CHECKSUMS.6095688" "/
+usr/local/src/perl/.cpan/sources/authors/id/S/ST/STRO/CHECKSUMS" 2> "
+/dev/null"
I didn't change anything for gpg. It was working fine earlier, but it isn't now. One thing that I did was install the latest CPAN. I've done a number of Google searches and can't find anything helpful. I've got a long list of packages that need to be installed and now I'm at a complete standstill. Does anyone have any ideas on what I need to check/change? Thanks.
I am analysing a LibreOffice Calc spreadsheet and need to manipulate a date field.
The values are seemingly read in OK but the parsing is not working somehow.
Code replicated below - ignore the positioning of the use statements, just trying to fathom out what is going on/how to get the result that I need and there are several spurious statements present that can probably be/will be redacted, including the print ones that I am using for monitoring purposes. The main If...then...else is still present due to having read in different formats previously (as alluded to) and finding that strptime gave different returns than I was expecting, hence the extra call to ParseDate
Date format used is in UK style dd/mm/YYYY
The date of 31/08/2024 works OK when read in
The data of 01/09/2024 (ie the next calendar day) gives gibberish - with the day coming out as 09 instead of 1, month as 01 instead of 9 and the year as 124.
Note that I have tried specifying the Zone in the ParseDate call but when I set it to GMT, the perl throws up an error about using barewords and using the directive of "ZONE => " does not help
I have tried various parsing calls using different utilities but I can't find one that behaves itself and consistently provides the correct answer or needs the parameters in a specific format (not impossible to do, just seems to be extra, unnecessary work)
I have also tried stepping through the relevant calls (eg strptime) at debugging run time but my perl is not good enough to decipher what is going on with the pattern matching algorithm
Therefore - any recommendations to code alterations/other better-behaved utilities would be gratefully received.
Also - anyone know why ParseDate returns a month one less than it should ?
many thanks
ADB
... code is read into $lCell variable ...
$lCell .= ""; # Force read detail into a string format, just in cas
+e (as I have seen ... !)
use Date::Parse;
use Date::Manip;
print ("$lCell ...\t");
my @ttt = strptime ($lCell);
my $yyy = ParseDate ($lCell,,);
#print "ADB $yyy...\n";
if ($yyy ne "")
{
# Format originally read was in the format 2024-08-09 before c
+onverting to string format
#code.
$lDay = substr($yyy,6,2);
$lMonth = substr($yyy,4,2);
$lYear = substr($yyy,0,4);
}
else
{
# Format was originally 16-08-2024 or similar
$lDay = $ttt[5];
# NOTE HERE that the month range in some perl modules has a ra
+nge 0..1 NOT 1..12, so adjust
$lMonth = $ttt[4] +1;
$lYear = $ttt[3];
}
I tested on two different installations that the debugger is activating a bunch of features when using it interactively.
I suppose it's doing a use VERSION internally activating features
It's kind of surprising because I provided a -e and not a -E in the prompt.
Is this documented behavior and if not shouldn't it be?
~$ perl -de0
Loading DB routines from perl5db.pl version 1.77
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 0
DB<1> p $]
5.038002
DB<2> use B::Deparse
DB<3> p B::Deparse->new->coderef2text(sub{})
{
use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'isa', 'm
+odule_true', 'postderef_qq', 'say', 'signatures', 'state', 'unicode_s
+trings', 'unicode_eval';
}
DB<4>
This is what happened. I downloaded the MSI installer for Perl 5.40.2.1 (2025-05-11). A fresh new Perl! Oh joy, oh excitement! oh ...NO. I did something bad. I configured the MSI installer to unpack Strawberry over my existing Strawberry installation (which was v5.32.1). Now I get various errors including the following:
perl -MWin32::Clipboard -e1
-e: Perl lib version (5.32.1) doesn't match executable 'C:\perl\perl\bin\perl.exe' version (5.40.2) at C:/perl/perl/lib/Config.pm line 62.
Pretty soon after this crippling of Strawberry on my system drive I installed the portable Strawberry onto a USB flash drive. I've made mention of that installation in other recent postings. Now it's working fine, BTW. But what I want to ask, what I am seeking, is: Is there any hope for my previous existing StrawberryPerl, or is it hopelessly trashed? I installed many modules from CPAN with that Strawberry, I'd really like to retrieve all the work that's gone into that installation.
The only thing I've thought of is going backwards and installing the older, previous Strawberry release on top of the new, broken one. I think that if I do so, perl will run. But not much else to be gained, perhaps.
If nothing else gets accomplished by this posting, maybe someone who is about to do what did will read it and be warned to NOT DO THAT.
Jun 09, 2025 at 19:12 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)