Ruby's File.exists becomes case insensitive?

Viewed 425

it's really strange, when I use File.exist? or File.exists? I found that it's case insensitive?

2.7.0-preview1 :001 > Dir.entries('.')
 => [".", "..", "ppp", "FOO", "Bar"] 
2.7.0-preview1 :002 > File.exist? "foo"
 => true 
2.7.0-preview1 :003 > File.exist? "FOO"
 => true 
2.7.0-preview1 :004 > File.exist? "FOOBAR"
 => false 
2.7.0-preview1 :005 > File.exists? "FOO"
 => true 
2.7.0-preview1 :006 > File.exists? "foo"
 => true 

How can I do a case sensitive File.exist? ? I'm using macOS Catalina 10.15.3


Update

For @Stefan question: why do I ask this question, it's simply I'm practicing the code snippet from the book - Ruby Cookbook ver.2, and the recipe is to rename files in bulk, like below:

require 'find'

module Find
  def rename(*paths)
    unrenamable = []
    find(*paths) do |file|
      next unless File.file? file # skip directory
      path, name = File.split(file)
      new_name = yield name

      if new_name && new_name != name
        new_path = File.join(path, new_name)
        if File.exist? new_path
          unrenamable << file
        else
          puts "Renaming #{file} to #{new_path}" if $DEBUG
          File.rename(file, new_path)
        end
      end
    end

    unrenamable
  end

  module_function(:rename)
end

and the first use case is to convert all files name to lowercase

File.rename('./') { |f| f.downcase }

The line if File.exist? new_path will be true if old_path and new_path are just different in upper or lower cases, then the all file are "unrenamable"

2 Answers

How can I do a case sensitive File.exist?

Use a case-sensitive file system.

This is one way around File.exist? being case insensitive:

def file_exist_case_sensitive(containing_dir, filename)
  Dir[File.join(containing_dir, "*")].select {|f| File.basename(f) == filename}.any?
end

Use it like:

file_exist_case_sensitive('/home/username/Desktop', 'my_file.txt')  #==> true
file_exist_case_sensitive('/home/username/Desktop', 'My_file.txt')  #==> false

I checked, that it's working on Ubuntu + ext4 and Windows 10 + NTFS, but you should use it carefully, as it might not work on some OSs or file systems.

Related