http://www.perlmonks.org?node_id=69565

perl that is. I've been pondering &DBI::connect() and why you have to give it strings like C:\\\\WINDOWS\\\\Desktop.

I got the first bit, that perl was interpolating the slashes when my first feeble attempt didn't work. So, &DBI::connect() really sees it as C:\\WINDOWS\\Desktop and then the function interpolates it again somewhere to get C:\WINDOWS\Desktop

That part is fairly simple, but I was happy to have figured that out on my own.

What was difficult for me to grasp was why perl interpolates the string a second time. I was still thinking in C. "Shouldn't perl just know that it's been interpolated once and not do it again? Wouldn't that be simpler?" I couldn't for the life of me figure it out. I knew there had to be a reason St. Larry did what he did. Like a flash, it just came to me last night while I was trying to sleep (avoid insomnia like the plague). If perl only interpolated strings once, you couldn't do stuff like

$foo="can I get you a \$bar?\n"; $bar="cow"; print $foo; $bar="chicken"; print $foo;
which is infinitly useful. And it's probably in the camel I've been reading. Perhaps it's time to RTFM again.

Update: No, I'm not. In fact, I'm rather wrong. No wonder it took so long to figure it out. And it's probably not in the camel either. Damn, I hate when that happens.

michael
the blue haired monk

Replies are listed 'Best First'.
Re: I think I'm starting to get it
by nashdj (Friar) on Apr 04, 2001 at 14:16 UTC
    If perl only interpolated strings once, you couldn't do stuff like...

    Maybe I'm completely off track and aren't understanding what you are saying. But since when does it interpolate twice?

    Your example there just gives me:

    can I get you a $bar? can I get you a $bar?
    I was under the impression that you could *only* interpolate within double quotations. (well, and a few other things). If you really did want it to interpolate twice there are some pointers at: Double Interpolation of a String.

    Also if you are dealing with win9x, most of the time c:/windows/desktop should function the same way as c:\\windows\\desktop. (unfortunately this seems to have changed in 2k, or maybe its an NT thing..)

(tye)Re: I think I'm starting to get it
by tye (Sage) on Apr 04, 2001 at 21:40 UTC

    Actually, Perl doesn't reinterpolate strings. Two backslashes should be enough. This sounds like a bug.

    As an example, if I do: $str= "C:\\Windows" and then try to use $str in a regular expression: if(  $path =~ /^$str/i  ) { then this won't work. But that is because I made a mistake. I should have written: if(  $path =~ /^\Q$str\E/i  ) { to tell the regular expression that I wanted it to parse $str as a string and not as a regular expression. (I also made a mistake in trying to use a regular expression to compare file paths as the resulting code is not portable.)

    I have a hard time coming up with cases other than regular expressions and eval where it is easy to get Perl to interpolate a string a second time. Perhaps you could do some more digging and find where this second interpolation is happening so that a fix could be made (or so I could understand why it isn't a bug in this case).

            - tye (but my friends call me "Tye")
      Am I missing something...
      $str= quotemeta 'C:\Windows'; if ( $path =~ /^$str/i ) { ...
      or...

      is that not a bit easier on the eyes :)

      As long as you use single quotes for $str it can stay readable...

      cLive ;-)

        That is (mostly) fine too.

        I prefer to tell the regex that I want it to treat the string as a string rather than transform the string into a regex that matches the old string, but most of my freinds know that I'm wierd.

        I also find that getting in the habit of using a single \ inside of single quotes is likely to bite you when you get used to it and try '\\server\share\dir' and can't figure out why you aren't finding those files.

                - tye (but my friends call me "Tye")
      Perl doesn't reinterpolate often but sometimes shells are involved when DBI calls are set up. Maybe that is where the issue is?

      --
      $you = new YOU;
      honk() if $you->love(perl)

      As I was working on getting DBD::CSV to work on my Windows98 maching with ActiveState Perl 5.6.0, I had some problems. $connectstr="C:\Windows\Desktop" didn't work. I got an error along the lines of "C:indowsesktop not found." (sorry, can't remember the actual error, but that's the gist of it. So then I put in an extra set of quotes $connectstr="C:\\Windows\\Desktop" and got the same error. So, after trying a few hundred different things, I got it to work with single quotes. I figured if it worked with single quotes, then putting more backslashes infront of the existing backslashes would work inside double quotes, which it did. Unfortunatly, I still don't know why it works.

      I looked into CSV.pm. It uses prototypes, which I don't get yet, and I don't have my camel handy. sub connect ($$;$$$) means (I think) two scalars, followed by three optional scalars. &DBD::CSV::connect() doesn't have a regex in it, but it does call &DBD::File::dr::connect() which does use a regex (one that is *way* beyond me now), which is where the problem comes from.

      I think that makes it not a bug, but something strange that isn't documented in DBD::CSV as far as I can tell.

      What do you think? Does any of this make sense?

      michael
      the blue haired monk

Re: I think I'm starting to get it
by ton (Friar) on Apr 05, 2001 at 01:21 UTC
    Actually, this has to do with the DBI module (I assume the db is a SQL-type?). Everyone else who has responded is correct: Perl does not double-interpret strings. In the case of DBI, however, Perl is passing a string to a database, which uses backslash for its own purposes (e.g. to escape '%' and '_', usually). As such, the database needs its own set of double backslashes so that it operates correctly.

    An example:

    my $string = "C:\\\\WINDOWS\\\\Desktop"; # $string is stored as "C:\\WINDOWS\\Desktop" DBI->somemethod($param1, $string); # Equivalent to DBI->somemethod($param1, 'C:\\WINDOWS\\Desktop')<BR>
    Hence, the quadruple bachslashes are needed because we have two programs, Perl and database, that need them escaped.