Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Perl Tutorial code uses "qw" but has an error when run

by Tio Cash (Novice)
on May 02, 2018 at 14:41 UTC ( [id://1213943]=perlquestion: print w/replies, xml ) Need Help??

Tio Cash has asked for the wisdom of the Perl Monks concerning the following question:


I am reading the Perl Tutorial on Regex: https://perldoc.perl.org/perlretut.html
The piece of code uses "qw" in front of a list of dates.
When I use the "qw" code from the tutorial , I get an error.
I went digging
I found an example of what "qw" looks like ('data1' , 'data2' , ...) without "qw"

If I remove the "qw" and then single quote the data and separate with a comma ; it works.

See below code where I comment out the code:
for my $d ( '2006-10-21', '15.01.2007', '10/31/2005' ) - success
OR
for my $d qw( 2006-10-21 15.01.2007 10/31/2005 ) - error msg

The results for each run are shown - error or success

Included below is web page , a do a "find" and sys information

Why is "qw" not working for me?




###################################################################
#### the bad - use "qw" ###########################################
###################################################################
C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>> type zz.pl



print("\n ######################### \n"); $fmt1 = '(?<y>\d\d\d\d)-(?<m>\d\d)-(?<d>\d\d)'; $fmt2 = '(?<m>\d\d)/(?<d>\d\d)/(?<y>\d\d\d\d)'; $fmt3 = '(?<d>\d\d)\.(?<m>\d\d)\.(?<y>\d\d\d\d)'; # for my $d ( '2006-10-21', '15.01.2007', '10/31/2005' ) for my $d qw( 2006-10-21 15.01.2007 10/31/2005 ) { if ( $d =~ m{$fmt1|$fmt2|$fmt3} ) { print "day=$+{d} month=$+{m} year=$+{y}\n"; } }



C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>> zz.pl

syntax error at C:\Users\cash_\Documents\Perl\02 Learn 21 Days\zz.pl line 7, near "$d qw( 2006-10-21 15.01.2007 10/31/2005 )"
Execution of C:\Users\cash_\Documents\Perl\02 Learn 21 Days\zz.pl aborted due to compilation errors.

C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>>


###################################################################
######## the good - use single quotes (') around data #############
###################################################################

C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>> type zz.pl

print("\n ######################### \n"); $fmt1 = '(?<y>\d\d\d\d)-(?<m>\d\d)-(?<d>\d\d)'; $fmt2 = '(?<m>\d\d)/(?<d>\d\d)/(?<y>\d\d\d\d)'; $fmt3 = '(?<d>\d\d)\.(?<m>\d\d)\.(?<y>\d\d\d\d)'; for my $d ( '2006-10-21', '15.01.2007', '10/31/2005' ) # for my $d qw( 2006-10-21 15.01.2007 10/31/2005 ) { if ( $d =~ m{$fmt1|$fmt2|$fmt3} ) { print "day=$+{d} month=$+{m} year=$+{y}\n"; } }



C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>> zz.pl


#########################
day=21 month=10 year=2006
day=15 month=01 year=2007
day=31 month=10 year=2005

C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>>



###################################################################
######## from the web page #############
######## https://perldoc.perl.org/perlretut.html #############
######## do a find on "Named backreferences" #############
###################################################################
perlretut
Perl 5 version 26.1 documentation
Named backreferences
Perl 5.10 also introduced named capture groups and named backreferences.
To attach a name to a capturing group, you write either (?<name>...) or (?'name'...).
The backreference may then be written as \g{name} .
It is permissible to attach the same name to more than one group, but then only the leftmost
one of the eponymous set can be referenced. Outside of the pattern a named capture group is accessible through the %+ hash.

Assuming that we have to match calendar dates which may be given in one of the three
formats yyyy-mm-dd, mm/dd/yyyy or dd.mm.yyyy, we can write three suitable patterns
where we use 'd' , 'm' and 'y' respectively as the names of the groups capturing the
pertaining components of a date. The matching operation combines the three patterns as alternatives:

$fmt1 = '(?<y>\d\d\d\d)-(?<m>\d\d)-(?<d>\d\d)';
$fmt2 = '(?<m>\d\d)/(?<d>\d\d)/(?<y>\d\d\d\d)';
$fmt3 = '(?<d>\d\d)\.(?<m>\d\d)\.(?<y>\d\d\d\d)';
for my $d qw( 2006-10-21 15.01.2007 10/31/2005 ){
if ( $d =~ m{$fmt1|$fmt2|$fmt3} ){
print "day=$+{d} month=$+{m} year=$+{y}\n";
}
}

If any of the alternatives matches, the hash %+ is bound to contain the three key-value pairs.



###################################################################
######## sys stuff #############
###################################################################


##################################################################
C:\Users\cash_\Documents\Perl\02 Learn 21 Days ==>> perl -v

This is perl 5, version 26, subversion 1 (v5.26.1) built for MSWin32-x64-multi-thread
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2017, Larry Wall

Binary build 2601 404865 provided by ActiveState http://www.ActiveState.com
Built Dec 11 2017 12:23:25

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

omplete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.



#################################################################
Host Name: CASH7
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.16299 N/A Build 16299
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Workstation
OS Build Type: Multiprocessor Free
Registered Owner: Windows User


System Manufacturer: Dell Inc.
System Model: Inspiron 5759
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
01: Intel64 Family 6 Model 78 Stepping 3 GenuineIntel ~2401 Mhz
BIOS Version: Dell Inc. 1.1.6, 2016-01-12

Replies are listed 'Best First'.
Re: Perl Tutorial code uses "qw" but has an error when run ( update Perldelta 5.14)
by LanX (Saint) on May 02, 2018 at 14:52 UTC
Re: Perl Tutorial code uses "qw" but has an error when run
by hippo (Bishop) on May 02, 2018 at 14:50 UTC

    Your error is not in the use of qw// but in the use of for. The list over which for iterates must be in brackets. See:

    $ perl -E 'for my $d qw( 2006-10-21 15.01.2007 10/31/2005 ) { say $d; +}' syntax error at -e line 1, near "$d qw( 2006-10-21 15.01.2007 10/31/20 +05 )" Execution of -e aborted due to compilation errors. $ perl -E 'for my $d (qw( 2006-10-21 15.01.2007 10/31/2005 )) { say $d +; }' 2006-10-21 15.01.2007 10/31/2005
Re: Perl Tutorial code uses "qw" but has an error when run
by toolic (Bishop) on May 02, 2018 at 14:59 UTC
    As others have explained, this syntax is no longer supported. This should be reported via perlbug so that the perlretut docs can be fixed. I will try to do this soon, unless someone beats me to it.

    UPDATED (2018 may 3): I submitted this as a perlbug.

      It was never supported. A bug in the parser merely allowed it despite being invalid syntax.

Re: Perl Tutorial code uses "qw" but has an error when run
by 1nickt (Canon) on May 02, 2018 at 14:52 UTC

    If you want to loop through the list with for you'll still have to use parens around the list that qw generates.

    $ perl -wE 'for my $d qw^ 2006-10-21 15.01.2007 10/31/2005 ^ { say $d +}' syntax error at -e line 1, near "$d qw^ 2006-10-21 15.01.2007 10/31/20 +05 ^" Execution of -e aborted due to compilation errors. $ perl -wE 'for my $d (qw^ 2006-10-21 15.01.2007 10/31/2005 ^) { say $ +d } ' 2006-10-21 15.01.2007 10/31/2005
    Note that I am using ^ for the qw delimiter to disambiguate from the list parens.

    Also note that you don't need the list parens if using a postfix for:

    $ perl -wE 'say $_ for qw^ 2006-10-21 15.01.2007 10/31/2005 ^' 2006-10-21 15.01.2007 10/31/2005

    Hope this helps!


    The way forward always starts with a minimal test.
Re: Perl Tutorial code uses "qw" but has an error when run
by stevieb (Canon) on May 02, 2018 at 14:53 UTC

    Sometime along the way, things were changed so that you couldn't any longer use an open qw() in a for loop, you must enclose the qw statement in an outer list:

    perl -wMstrict -E 'for my $d (qw(1 2 3)){say $d}' 1 2 3

    I do not have time to dig through the perldeltas right now, but switching to 5.10.1, the following works:

    perl -wMstrict -E 'for my $d qw(1 2 3){say $d}' 1 2 3


      Thanks Gang !

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1213943]
Approved by toolic
Front-paged by LanX
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-23 16:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found