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

I have hit this error several time lately (since the advent of 5.6.0 ?). A Google search produced 7 problem reports, btw Jun 2000 and now, with a variety of Perl modules, including PPM and ExtUtils::Installed. It can crop up easily on Win32 if you use the native pathnames containing '\' path separator. Here are examples:
#! perl -w use strict; # 1: no problem (even on Win32) # my $root = 'C:/perl'; my $podfile = 'C:/Perl/lib/Config.pm'; print "$podfile $root $1 $2\n" if $podfile =~ m!$root/(.*)/(\w+) +\.p.+$!i; # 2: causes error # my $rootb = 'C:\perl'; my $podfileb = 'C:\Perl\lib\Config.pm'; print "$podfileb $rootb $1 $2\n" if $podfileb =~ m!$rootb/(.*)/( +\w+)\.p.+$!i; # 3: simplified, causes error # print "yo\n" if 'perl' =~ m|\perl|; __END__
It turns out that the problem is related to the recently added regex feature, mentioned briefly in perlre like so
In addition, Perl defines the following: ... \pP Match P, named property. Use \p{Prop} for longer names. \PP Match non-P
Apparently,  m|\perl| means: match a property named 'e' which might be defined in a script or in the main module - but it is not defined, in my case.

On Win2k you can easily get a pathname containing '\p' or '\P' from a module such as File::Find or Config
print "==$Config{installprefix}==\n"; # prints ==C:\Perl==
The workaround is to replace backslashes by slashes before using such paths in a matching operation
$podfileb =~ s!\\!/!g; $rootb =~ s!\\!/!g;
However, if a path containing backslashes is being passed between code inside a module, you might have to dig deeply if you want to fix it.

Questions to wise Monks: Rudif
  • Comment on Can't find unicode character property definition via main-e or e.pl at unicode/Is/e.pl line 0
  • Select or Download Code

Replies are listed 'Best First'.
(tye)Re: Can't find unicode character property definition via main-e or e.pl at unicode/Is/e.pl line 0
by tye (Sage) on Mar 18, 2001 at 13:31 UTC

    It turns out that the problem is related to the recently added regex feature

    No, the problem is using a regex to match a literal string without telling it that this is what you wanted to do! The recent \p regex addition just made these bugs more noticeable.

    If you ever see a regex with $var in it, you should suspect that \Q$var\E is what should have been used. Looking through Config.pm, I only find one (uncommented) case of this mistake, but it is probably fine since the $var in that case should only contain letters.

    So are you the one coding regexen incorrectly this way? If so, the solution is quite simple. If you replace m!$rootb/(.*)/(\w+)\.p.+$!i; with m!\Q$rootb\E/(.*)/(\w+)\.p.+$!i;, for example, then that problem goes away.

    Next you have to deal with your misconception that you can use a single character as the directory separator. I suggest you look into File::Spec instead of hand-rolled regexen for comparing paths.

            - tye (but my friends call me "Tye")
      Thank you, tye, for the insight and advice.

      I met this problem recently while working on the original version of this script, from the module Pod-Tree-1.06. Path strings containing '\' were passed to the script as arguments by the user (me), and the script hit the error while doing the substitution
      $dir =~ s/^$PodDir/$HTMLDir/o;
      I did not understand the problem at the time, but I found that I could fix it by inserting
      # fix up the Win32 paths $PodDir =~ s( \\ )(/)gx; $HTMLDir =~ s( \\ )(/)gx;
      Now you explained the nature of the problem and showed two ways to make similar scripts more robust:
      • Apply quotemeta or \Q\E to a user-supplied string before using it in a regex.
      • File::Spec provides platform-independent operations on path strings, notably splitting, catenating and converting absolute paths to relative, and should be used in portable scripts.
      Rudif

      Thank you for this answer Tye. I ran into this issue as well, except the error message contained "main-a or a.pl at unicode/Is/a.pl line 546". The <code>\Q\E character combination did the deal for me as well.
      tye, I've run into this same item in unum.pl, which I'm trying to run on an + n810. $ unum c=`cat /home/user/hebrew.utf8` Can't find unicode character property definition via main->IsDigit or +Is/Digit.pl at /home/user/bin/unum.pl line 194 $ sed -ne '194p' /home/user/bin/unum.pl if ($n =~ m/^\d/) { I'm not familiar enough with PERL syntax to see how to apply the \Q\E. The line giving the error is: Line 194: if ($n =~ m/^\d/) { It doesn't seem right to me to change $n to \Q$n\E because it is not i +n the m// expression. At the same time, I don't see a $var in the m// expression. I'm feeling rather dense, as I look at this. What is the proper syntax for this line? John
        The line giving the error is:
        Line 194: if ($n =~ m/^\d/) {

        No, that line can't be to blame. Which means the problem is actually on a subsequent elsif line (that is an annoying quirk of how Perl reports line numbers for error messages -- an error in the conditional expression of an elsif is always reported as happening on the line of the corresponding if expression instead). If you don't see how to fix that line, then reply back.

        - tye