File, relative path handling

Before I attempt to re-invent this wheel:
Has anyone come up with a method for converting an absolute
filesystem path into a relative path, given the path to relate to?
Pruning off the front is relatively easy, but handling '…/'
correctly is likely to be error prone. Given that I need to cope
with Ruby 1.6 and 1.8 at the moment, and I will need to do something
graceful if the paths are on different Windows drives, well, I
suspect someone has run into this before me.

I need relative paths so I can move between data sets for testing
and between machines as well.

    Thank you,
    Hugh

Hugh,

Has anyone come up with a method for converting
an absolute filesystem path into a relative
path, given the path to relate to?

Well, this doesn't handle Windows drive letters, but it handles the

rest:

Convert the given absolute path into a path

relative to the second given absolute path.

def relativepath(abspath,relativeto)
path = abspath.split(File::SEPARATOR)
rel = relativeto.split(File::SEPARATOR)
while (path.length > 0) && (path.first == rel.first)
path.shift
rel.shift
end
(‘…’ + File::SEPARATOR) * (rel.length - 1) + path.join(File::SEPARATOR)
end

I hope this helps.

- Warren Brown

Hugh Sasse Staff Elec Eng wrote:

Before I attempt to re-invent this wheel:
Has anyone come up with a method for converting an absolute
filesystem path into a relative path, given the path to relate to?
Pruning off the front is relatively easy, but handling ‘…/’
correctly is likely to be error prone. Given that I need to cope
with Ruby 1.6 and 1.8 at the moment, and I will need to do something
graceful if the paths are on different Windows drives, well, I
suspect someone has run into this before me.

I need relative paths so I can move between data sets for testing
and between machines as well.

Strange you should ask. I just wrote one of these and was about to port
it, and some other string utilities, to a C extension object.

It’s brutal, but it works. Feel free to Rubify, anyone:

class String
public
def relative_path(topath)
frompath = self.clone
topath = topath.clone

 fromdir = frompath.slice(/^.*?\//)
 while(fromdir and frompath.slice(/^.*?\//) == topath.slice(/^.*?\//))
   topath.slice!(/^.*?\//)
   fromdir = frompath.slice!(/^.*?\//)
 end

 fromdir = frompath.slice!(/^.*?\//)
 while(fromdir)
   topath = "../" + topath
   fromdir = frompath.slice!(/^.*?\//)
 end

 return topath

end

def relative_path!(topath)
self.replace(relative_path(topath))
end
end

Sean O'Dell

Warren Brown wrote:

Hugh,

Has anyone come up with a method for converting
an absolute filesystem path into a relative
path, given the path to relate to?

Well, this doesn't handle Windows drive letters, but it handles the

rest:

Convert the given absolute path into a path

relative to the second given absolute path.

def relativepath(abspath,relativeto)
path = abspath.split(File::SEPARATOR)
rel = relativeto.split(File::SEPARATOR)
while (path.length > 0) && (path.first == rel.first)
path.shift
rel.shift
end
(‘…’ + File::SEPARATOR) * (rel.length - 1) + path.join(File::SEPARATOR)
end

Your relative path routine is MUCH more efficient than mine, geez. I
still don’t “think” with everything Ruby has to offer. I’m still too
much of a “got-no-libs” C/C++ person. =)

Sean O'Dell

I suggest to put that on the Wiki - if it’s not already there.

robert

“Warren Brown” wkb@airmail.net schrieb im Newsbeitrag
news:002001c3762a$36d81260$803888cf@warrenpc…

Hugh,

Has anyone come up with a method for converting
an absolute filesystem path into a relative
path, given the path to relate to?

Well, this doesn't handle Windows drive letters, but it handles the

rest:

Convert the given absolute path into a path

relative to the second given absolute path.

def relativepath(abspath,relativeto)
path = abspath.split(File::SEPARATOR)
rel = relativeto.split(File::SEPARATOR)
while (path.length > 0) && (path.first == rel.first)
path.shift
rel.shift
end
(‘…’ + File::SEPARATOR) * (rel.length - 1) +
path.join(File::SEPARATOR)

···

end

I hope this helps.

- Warren Brown

I suggest to put that on the Wiki - if it’s not already there.

robert

Oh! I seem to have missed this mssage [RubyTalk:81378], but these
often arrive out of sequence. This is a nice solution, and since at
the moment I’m keeping all the stuff on the same drive I can live
without the drive letter for now. This is much more elegant a
solution that I would have created. Thank you.

“Warren Brown” wkb@airmail.net schrieb im Newsbeitrag
news:002001c3762a$36d81260$803888cf@warrenpc…
[elided for brevity]

    Thank you,
    Hugh
···

On Tue, 9 Sep 2003, Robert Klemme wrote: