Feature #8258

Dir#escape_glob

Added by Steve Klabnik about 1 year ago. Updated about 1 year ago.

[ruby-core:54207]
Status:Open
Priority:Normal
Assignee:-
Category:-
Target version:-

Description

This is inspired by https://github.com/rails/rails/issues/6010.

Basically, if you do a Dir.glob in a directory whose name contains a glob character, things break. It would be nice to have a method which would escape the input so that we can Dir.glob inside of those directories.

History

#1 Updated by Konstantin Haase about 1 year ago

File.fnmatch_escape would make more sense, imo.

#2 Updated by Charles Nutter about 1 year ago

rkh (Konstantin Haase) wrote:

File.fnmatch_escape would make more sense, imo.

But it would be harder to remember when what you want is "glob" :-)

Why not just {Dir,File}.quote or .escape, to match Regexp.quote/escape? I would vote for File.escape, a method that escapes any file path to make it suitable for globbing.

#3 Updated by Steve Klabnik about 1 year ago

I don't feel strongly about the name, specifically.

#4 Updated by Benoit Daloze about 1 year ago

headius (Charles Nutter) wrote:

rkh (Konstantin Haase) wrote:

File.fnmatch_escape would make more sense, imo.

But it would be harder to remember when what you want is "glob" :-)

Why not just {Dir,File}.quote or .escape, to match Regexp.quote/escape? I would vote for File.escape, a method that escapes any file path to make it suitable for globbing.

I agree, this would be strictly superior.

I guess the most common use case is globbing on a directory recursively, so only the base directory is to be escaped, but this is not worth a specific method I think and could be done easily: Dir.glob("#{Dir.escape dir}//*.rb") { |file| ... }
Pathname could likely avoid this problem nicely in this situation: dir = Pathname("some_dir"); dir.glob("
/*.rb") { |file| ... }

#5 Updated by Benoit Daloze about 1 year ago

What is more worrying is implementations differ quite a bit in treating \ as an escape for these glob characters ({,},[,],*,?).

From my tests:
- MRI handle them fine
- Rubinius does not handle escaped [, { and }.
- JRuby does not handle escaped and

If I am not mistaken, escaping is as simple as: dir.gsub(/[|]|*|\?|{|}/, '\\' + '\0').

#6 Updated by Konstantin Haase about 1 year ago

  • Rubinius does not handle escaped [, { and }.
  • JRuby does not handle escaped [ and ]

These are implementation bugs, imo, and nothing to worry about here.

If I am not mistaken, escaping is as simple as: dir.gsub(/[|]|*|\?|{|}/, '\\' + '\0').

Yes, but it shifts responsibility for keeping this up to date from the user code to the Ruby implementation, and should be flag dependent. I.e. Ruby 2.0 introduced the EXTGLOB flag.

#7 Updated by Benoit Daloze about 1 year ago

rkh (Konstantin Haase) wrote:

  • Rubinius does not handle escaped [, { and }.
  • JRuby does not handle escaped [ and ]

These are implementation bugs, imo, and nothing to worry about here.

But it means the problem will not be solved in the general case before a while.
It must also have been problematic for some time, so I guess we are not in a hurry either.

If I am not mistaken, escaping is as simple as: dir.gsub(/[|]|*|\?|{|}/, '\\' + '\0').

Yes, but it shifts responsibility for keeping this up to date from the user code to the Ruby implementation,

I agree there should be Dir.escape or Dir.escape_glob.

and should be flag dependent. I.e. Ruby 2.0 introduced the EXTGLOB flag.

Can you give examples? If it works for every case except FNM_NOESCAPE, I think it is better to have a single simple way.

#8 Updated by Nobuyoshi Nakada about 1 year ago

(13/04/14 18:34), Eregon (Benoit Daloze) wrote:

I guess the most common use case is globbing on a directory recursively, so only the base directory is to be escaped, but this is not worth a specific method I think and could be done easily: Dir.glob("#{Dir.escape dir}/*/.rb") { |file| ... }

It reminded me about old proposal, Dir#glob (not Dir.glob).

--
Nobu Nakada

#9 Updated by Benoit Daloze about 1 year ago

nobu (Nobuyoshi Nakada) wrote:

It reminded me about old proposal, Dir#glob (not Dir.glob).

Interesting, do you have a link?

Also available in: Atom PDF