in reply to spaces in filenames

Update: Thanks to MarkM for pointing out that split() accepts a scalar as its first argument just fine, provided you escape the \'s

I think the problem lies in your call to split(). You should pass a pattern as its first argument, but instead you're passing a scalar. Later I provide a proper example. This is a test of utime() on my system, just so we know this is not culprit.

bash-2.05a$ touch "my file"
bash-2.05a$ ls -l "my file"
-rw-r--r--  1 lem  staff  0 Feb  2 21:28 my file
bash-2.05a$ sleep 60; perl -e 'print utime(undef, undef, "my file"), "\n";'
1
bash-2.05a$ ls -l "my file"
-rw-r--r--  1 lem  staff  0 Feb  2 21:29 my file

Also, you should be checking the return value of utime(). When it fails, returns a false value. You could then use the special variable $! to see a (hopefully) meaningful error message. See perlvar for more info on this variable.

Your code is otherwise fine (I guess) but I would like to offer a shorter and untested alternative...

open(CSV, "/tmp/doctime.txt") or die "Failed to open CSV: $!\n"; while (my $line = <CSV>) { my @val = split(/,/, $line, 2); unless (utime $val[0], $val[0], $val[1]) { warn "Failed to utime $val[1]: $!\n"; } } close CSV;

++ for -w, but you should also use strict.

Best regards

-lem, but some call me fokat

Replies are listed 'Best First'.
Re: Re: spaces in filenames
by dvergin (Monsignor) on Feb 03, 2003 at 03:09 UTC
    You say:
    You should pass a pattern as its first argument, but instead you're passing a scalar.

    Yes, split does expect a pattern. But no, it does not have to be delimited with forward slashes. In fact, Perl doesn't even require delimiters here. A scalar value in a variable will be interpreted as a pattern also. Either of the following cases works fine...

    my $str = 'this_is_a_group_of_words'; my @ary = split "_", $str; print "[$_]\n" for @ary; my $str = 'this_is_a_group_of_words'; my $pat = '_'; my @ary = split $pat, $str; print "[$_]\n" for @ary;
    perldoc -f split says "The pattern "/PATTERN/" may be replaced with an expression to specify patterns that vary at run-time." but then confuses things by going on with, "(To do runtime compilation only once, use "/$variable/o".)" which makes it look like you still need the slashes. (Which you do if you want to add the '/o'.)

    Camel 3, page 796, is more clear on this point when it says "if you supply a string instead of a regular expression, it will be interpreted as a regular expression anyway."

    ------------------------------------------------------------
    "Perl is a mess and that's good because the
    problem space is also a mess.
    " - Larry Wall

      dvergin said:

      A scalar value in a variable will be interpreted as a pattern also.

      I beg to differ. Take a look at the code below:

      bash-2.05a$ perl -e 'print scalar(split("\W", "one two three")), "\n";'
      1
      bash-2.05a$ perl -e 'print scalar(split("\\W", "one two three")), "\n";'
      3
      bash-2.05a$ perl -e 'print scalar(split(/\W/, "one two three")), "\n";'
      3
      

      As you see, both versions produce a different result. My interpretation of your quote to The Camel (and to the fact that the original code compiles at all), is that split() is using the literal string as exactly that, a literal string that must occur verbatim.

      This might have changed at some time, though. I have vague recollections of using a literal with split(), but that was way back I guess. I am running 5.8.0 here, BTW.

      ++ for dvergin for researching his answer :)

      Update: As pointed out by MarkM, the literal string is indeed interpreted as a regular expression. It's just that \ must be escaped in my example, so my conclusion turned out to be wrong. ++ to MarkM for showing me the light...

      Best regards

      -lem, but some call me fokat

        You are correct that "\W" produces a different result from /\W/ as a first argument to split(). You are not correct in concluding that this means split() is assuming that a quoted string is a literal. Examples:

        $ perl -e '$t = "abc,def"; @t = split("\\W", $t); print "@t\n"' abc def
        $ perl -e '$a = "abc,def"; @a = split("[^a-z]", $a); print "@a\n"' abc def

        In both cases, the string is being interpretted as a regular expression. As a string, a different set of interpolation rules apply.