0

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.

3
  • It this CORE::glob or :bsd_glob from perldoc.perl.org/File/Glob.html? Commented Feb 1, 2017 at 14:30
  • The requests come from our iOS app. So there is some delay between the code that runs. To run it 3 times takes around 5 seconds. Commented Feb 1, 2017 at 14:31
  • Assigning the result of glob to an array will fix this, and it's highly likely that you'll want to know the names of the files as well as just whether they exist. Commented Feb 1, 2017 at 19:16

1 Answer 1

3

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 
Sign up to request clarification or add additional context in comments.

3 Comments

Wow. That is some really wierd code. I tried it though. And it worked just the way I wanted it to. Thanks!
There's some good discussion on scalar glob at this question.
Using symbolic identifiers like that is discouraged because they are reserved for Perl built-in variables. It is also highly inconsiderate to write code using undefined symbolic variables with spaces in unusual places, as most Perl programmers will be unable to parse it quickly. The obvious way to check the existence of files matching a glob pattern is with if ( my @files = glob 'aaa:*' ) { ... } where the array @files is defined only for the length of the if block. "secret operators" are mostly infantile toys rather than valid constructs for use in production software

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.