Feature #21766
openPathname + FileUtils making sweet music together
Description
I love Pathname. I love FileUtils. Let's bring these two classes EVEN CLOSER TOGETHER by adding some tragically missing helpers. Something like this, perhaps?
class Pathname
def mkdir_p(...) = FileUtils.mkdir_p(@path, ...)
def ln(...) = FileUtils.ln(@path, ...)
def ln_s(...) = FileUtils.ln_s(@path, ...)
def ln_sf(...) = FileUtils.ln_sf(@path, ...)
def cp(...) = FileUtils.cp(@path, ...)
def cp_r(...) = FileUtils.cp_r(@path, ...)
def mv(...) = FileUtils.mv(@path, ...)
def rm(...) = FileUtils.rm(@path, ...)
def rm_r(...) = FileUtils.rm_r(@path, ...)
def rm_rf(...) = FileUtils.rm_rf(@path, ...)
end
There are some concerns about making pathname.rb more dependent on FileUtils, which I understand. What's the best way forward? Let's do it!
(also see https://github.com/ruby/pathname/issues/64 and https://github.com/ruby/pathname/issues/72)
Updated by Dan0042 (Daniel DeLorme) 14 days ago
Remember that FileUtils is loaded dynamically, so it would be something like
class Pathname
def mkdir_p(...) = _fileutils(:mkdir_p, ...)
def ln(...) = _fileutils(:ln, ...)
def ln_s(...) = _fileutils(:ln_s, ...)
def ln_sf(...) = _fileutils(:ln_sf, ...)
def cp(...) = _fileutils(:cp, ...)
def cp_r(...) = _fileutils(:cp_r, ...)
def mv(...) = _fileutils(:mv, ...)
def rm(...) = _fileutils(:rm, ...)
def rm_r(...) = _fileutils(:rm_r, ...)
def rm_rf(...) = _fileutils(:rm_rf, ...)
private def _fileutils(name, ...)
require "pathname/fileutils"
send(name, ...)
end
end
#pathname/fileutils.rb
require "fileutils"
class Pathname
def mkdir_p(...) = FileUtils.mkdir_p(@path, ...)
def ln(...) = FileUtils.ln(@path, ...)
def ln_s(...) = FileUtils.ln_s(@path, ...)
def ln_sf(...) = FileUtils.ln_sf(@path, ...)
def cp(...) = FileUtils.cp(@path, ...)
def cp_r(...) = FileUtils.cp_r(@path, ...)
def mv(...) = FileUtils.mv(@path, ...)
def rm(...) = FileUtils.rm(@path, ...)
def rm_r(...) = FileUtils.rm_r(@path, ...)
def rm_rf(...) = FileUtils.rm_rf(@path, ...)
end
Updated by gurgeous (Adam Doppelt) 14 days ago
I'm open to any and all implementation suggestions, happy to do whatever is required. I just want the feature!
Updated by zverok (Victor Shepelev) 14 days ago
I am thinking in this direction: it is not unseen for standard libraries, when required, to add methods to core objects:
{a: 1}.to_json # NoMethodError
require 'json'
{a: 1}.to_json #=> {"a": 1}
Time.parse('12:20') # NoMethodError
require 'time'
Time.parse('12:20') #=> 2025-12-08 12:20:00 +0200
Why not this, then?
Pathname('tmp.txt').cp('tmp/') # NoMethodError
require 'fileutils'
Pathname('tmp.txt').cp('tmp/') # Works
As Pathname have became core object, it seems to be OK for a library like fileutils to be aware of it and extend it?
Updated by akr (Akira Tanaka) 10 days ago
I feel Unix command names are too short for usual programs.
So, I'm negative.
Updated by zverok (Victor Shepelev) 10 days ago
I feel Unix command names are too short for usual programs.
At the same time:
- they are known at least to most of the console-using programmers, so this is a "dictionary" many of us familiar with
- FileUtils have a practice of aliasing them to more common words (
cpascopy,mvasmove, and so on) which Pathname can borrow, too.Pathname.new('test.txt').move('tmp/')is perfectly clear and unambiguous.