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

This code prepends a path to an NT enviromental %PATH%.

Having this code:
#!/usr/bin/perl -w use strict; my $Registry; my $newpath='C:\Perl\bin'; use Win32::TieRegistry ( TiedRef=>\$Registry, Delimiter=>"/", ArrayVal +ues=>1 ); my $env= $Registry->{"LMachine/System/CurrentControlSet/Control/". "Session Manager/Environment/"} or die "Can't open CCS/SM/Env: $^E\n"; my $path= $env->{"/PATH"} or die "Can't get PATH: $^E\n"; #Prepend to path if ($path->[0] =~ /$newpath/ ) { print "$newpath is already in your PATH\n"; } else { print "Here\n"; $path->[0]= $newpath . "$path->[0]"; print "Path is now $path->[0]\n"; $env->{"/PATH"}= $path or die "Can't set PATH: $^E\n" }
I know my bug is in the if ($path->[0] =~ /$newpath/ ) statement, but I'm not sure how to fix the bug. How can I search for $newpath without searching for the regular expression $newpath?

Thanks in advance.

Replies are listed 'Best First'.
Re: Trying to determine if path exists in environmental variable
by dpuu (Chaplain) on Aug 16, 2002 at 23:13 UTC
    I'd try a split and a grep:
    my $list = "foo:bar:baz"; my $wanted = "bar"; if (grep {$_ eq $wanted) split ":", $list) { print "found!\n"; }
    --Dave
Re: Trying to determine if path exists in environmental variable
by Zaxo (Archbishop) on Aug 16, 2002 at 23:36 UTC

    Your $newpath contains regex metacharacters. Change the regex to escape them by:

    if ( $path->[0] =~ /\Q$newpath\E/ )
    The '\b' in $newpath is interesting, The match /l\bi/ cannot match anything, since '\b' is a zero-width word boundary and 'li' does not contain one :)

    In a larger issue, the File::Spec module can help with this task.

    After Compline,
    Zaxo

Re: Trying to determine if path exists in environmental variable
by tachyon (Chancellor) on Aug 16, 2002 at 23:51 UTC

    While the problem occurs in the if() clause the cause is the value of $newpath and the lack of a quotemeta which should be considered mandatory when interpolating a variable into the match side of a regex

    my $newpath='C:\Perl\bin'; .... if ($path->[0] =~ /$newpath/ ) # perl sees this as ... =~/C:\Perl\bin/; # you need either to $newpath = quotmeta $newpath # or do it in the match =~/\Q$newpath/

    With quotemeta your code runs as expected.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Trying to determine if path exists in environmental variable
by slojuggler (Beadle) on Aug 17, 2002 at 01:38 UTC
    Here's the final code. I implemented Zaxo's suggestion.

    Thanks to all who helped. Hope you find this code useful!

    #!/usr/bin/perl -w =pod This script adds paths into the system path. Simply change @newpaths to reflect the directories you'd like to add. Author: P. Rivera Portions inspired by: Marza/Perlmonks, node 156805; Zaxo and various monks, node 190779 =cut use strict; my $Registry; my $newpath; my @newpaths=('P:\Scripts\Admin','P:\Scripts\Anly','P:\Perl\bin'); use Win32::TieRegistry ( TiedRef=>\$Registry, Delimiter=>"/", ArrayVal +ues=>1 ); my $env= $Registry->{"LMachine/System/CurrentControlSet/Control/". "Session Manager/Environment/"} or die "Can't open CCS/SM/Env: $^E\n"; my $path= $env->{"/PATH"} or die "Can't get PATH: $^E\n"; print "Path currently is $path->[0]\n\n"; print "-" x 65 . "\n"; for $newpath (@newpaths) { print "Attempting to prepend $newpath to path.\n\n"; #See if new path is the system PATH if ($path->[0] =~ /\Q$newpath\E/ ) { print "$newpath is already in your system PATH. Not ad +ded again.\n"; } else { $path->[0]= $newpath . ";$path->[0]"; print "Path is now $path->[0]\n\n"; $env->{"/PATH"}= $path or print "Can't set PATH!!: $^E +\n"; } print "-" x 65 . "\n"; }
(tye)Re: Trying to determine if path exists in environmental variable
by tye (Sage) on Aug 17, 2002 at 05:35 UTC
Re: Trying to determine if path exists in environmental variable
by slojuggler (Beadle) on Aug 16, 2002 at 23:12 UTC
    P.S. The if line causes the error: Can't find unicode character property definition via main->e or e.pl at unicode/Is/e.pl line 0

    If I change the line to

    if (1)

    no error persists, but then the program doesn't do what it's supposed to do. :-)