Search code examples
perlglob

perl glob check if file with prefix exists


I get some strange behaviour searching for files using glob. (I think its intended, but I don't want it in my case)

I have 2 files named aaa:bbb and aaa:ccc.

I have code to see if files with prefix aaa:* exists. I do this with this code:

my $filelocation_special = "aaa";

if (glob($filelocation_special . ":*")) {
  # file(s) exists!
}

This works. However, if I run the same code again two more times glob returns undefined.

these are my returns: (most of the time anyway)

print STDERR "glob: " . glob($filelocation_special . ":*") . "\n";

# 1 run: aaa:bbb
# 2 run: aaa:ccc
# 3 run: 

What can I do to reset globto always just check if files with this prefix exists?

Maybe I should use some different check altogether, but I can't seem to find anything that is fast and just checks if the files exists.


Solution

  • if (glob(...)) is a call to glob in scalar context.

    In scalar context, glob iterates through such filename expansions, returning undef when the list is exhausted.

    So everytime you call glob in scalar context, with the same arguments, and from the same line of code, you will get a different result, and eventually you will get undef when the list of files that match your argument are exhausted.

    To get your expression to mean "if there are files that match this pattern ...", you need to use list context somehow.

    @tmp = glob(pattern)
    if (@tmp) 
    
    if (()=glob(pattern))
    
    if (@{[glob(pattern)]})
    


    Diversion: any of these also work (because @* are valid global array identifiers for many values of punctuation character *)

    if (@@=glob(pattern))
    if (@<=glob(pattern))
    if (@:=glob(pattern))
    

    and they can even be written like

    if (@ <= glob(pattern))
    if (@ := glob(pattern))
    

    and so a few more candidates for secret operators are suggested.

    @@ = EXPR       like the goatse operator, returns a count of elements
    @ <= EXPR       in EXPR when EXPR is evaluated in list context; useful
    @ := EXPR       when EXPR in scalar context does not do this