File.expand_path(__FILE__)

I’m having a problem with File.expand_path(FILE) after a chdir.
Looks like a bug in Ruby to me. If someone can tell me what I’m doing
wrong, I’d be grateful.

Here’s the reduction:

[ryan@kursk 15:26:38 ~]$ cat tmp/demo-problem.rb
puts "starting working directory: " + Dir.getwd
puts "expand_path: " + File.expand_path(FILE)
puts "about to change to dirname of FILE: " + FILE
Dir.chdir(File.dirname(FILE))
puts "new working directory: " + Dir.getwd
puts "expand_path: " + File.expand_path(FILE)

[ryan@kursk 15:26:40 ~]$ cd tmp

[ryan@kursk 15:26:44 ~/tmp]$ ruby demo-problem.rb
starting working directory: /Users/ryan/tmp
expand_path: /Users/ryan/tmp/demo-problem.rb
about to change to dirname of FILE: demo-problem.rb
new working directory: /Users/ryan/tmp
expand_path: /Users/ryan/tmp/demo-problem.rb

[ryan@kursk 15:26:45 ~/tmp]$ cd …

[ryan@kursk 15:26:50 ~]$ ruby tmp/demo-problem.rb
starting working directory: /Users/ryan
expand_path: /Users/ryan/tmp/demo-problem.rb
about to change to dirname of FILE: tmp/demo-problem.rb
new working directory: /Users/ryan/tmp
expand_path: /Users/ryan/tmp/tmp/demo-problem.rb

[ryan@kursk 15:26:56 ~]$

···


Ryan “John” Platte
Custom services, NIKA Consulting
http://nikaconsulting.com/

I’m having a problem with File.expand_path(FILE) after a chdir.
Looks like a bug in Ruby to me. If someone can tell me what I’m doing
wrong, I’d be grateful.

Here’s the reduction:

[ryan@kursk 15:26:38 ~]$ cat tmp/demo-problem.rb
puts "starting working directory: " + Dir.getwd
puts "expand_path: " + File.expand_path(FILE)
puts "about to change to dirname of FILE: " + FILE
Dir.chdir(File.dirname(FILE))
puts "new working directory: " + Dir.getwd
puts "expand_path: " + File.expand_path(FILE)

                                      ^^^^^^^^
                                        BOOM

I guess you assume that FILE change when doing chdir.
But it doesn’t

ruby a.rb
“a.rb”
“/tmp”
“a.rb”
“/”
“a.rb”
“/tmp”
expand -t2 a.rb
p FILE, Dir.pwd
Dir.chdir(“…”) do
p FILE, Dir.pwd
end
p FILE, Dir.pwd

As you can see, filenames doesn’t change during chdir.

HTH,

···

On Fri, 30 Apr 2004 05:28:43 +0900 John Platte john.platte@nikaconsulting.com wrote:


Simon Strandgaard

Simon Strandgaard wrote:

I’m having a problem with File.expand_path(FILE) after a chdir.
Looks like a bug in Ruby to me. If someone can tell me what I’m doing
wrong, I’d be grateful.

I guess you assume that FILE change when doing chdir.
But it doesn’t

I think you’ve analyzed this incorrectly.

The value of FILE doesn’t change, nor did he expect it to.
But expand_path is giving him an erroneous result, is it not?

“/Users/ryan/tmp/tmp/demo-problem.rb” – there is no tmp/tmp
directory if I understand correctly.

It does look like a bug to me.

Hal

···

On Fri, 30 Apr 2004 05:28:43 +0900 > John Platte john.platte@nikaconsulting.com wrote:

No bug.

At the last line “File.expand_path(FILE)” is being invoked.
Currend dir = “/Users/ryan/tmp/”
File name = “tmp/demo-problem.rb”

When these are being concatenated it outputs
absolut path = “/Users/ryan/tmp/tmp/demo-problem.rb”

concat is working ok.

···

Hal Fulton hal9000@hypermetrics.com wrote:

Simon Strandgaard wrote:

On Fri, 30 Apr 2004 05:28:43 +0900 > > John Platte john.platte@nikaconsulting.com wrote:

I’m having a problem with File.expand_path(FILE) after a chdir.
Looks like a bug in Ruby to me. If someone can tell me what I’m doing
wrong, I’d be grateful.

I guess you assume that FILE change when doing chdir.
But it doesn’t

I think you’ve analyzed this incorrectly.

The value of FILE doesn’t change, nor did he expect it to.
But expand_path is giving him an erroneous result, is it not?

“/Users/ryan/tmp/tmp/demo-problem.rb” – there is no tmp/tmp
directory if I understand correctly.

It does look like a bug to me.


Simon Strandgaard

Simon Strandgaard wrote:

No bug.

At the last line “File.expand_path(FILE)” is being invoked.
Currend dir = “/Users/ryan/tmp/”
File name = “tmp/demo-problem.rb”

When these are being concatenated it outputs
absolut path = “/Users/ryan/tmp/tmp/demo-problem.rb”

concat is working ok.

expand_path doesn’t simply concatenate. If it did, we could
simply do dir + name.

Taking a valid relative pathname and returning an invalid
absolute pathname is not useful, certainly not a feature.

If not a bug, at least an anomaly.

Hal

Simon Strandgaard wrote:

No bug.

At the last line “File.expand_path(FILE)” is being invoked.
Currend dir = “/Users/ryan/tmp/”
File name = “tmp/demo-problem.rb”

When these are being concatenated it outputs
absolut path = “/Users/ryan/tmp/tmp/demo-problem.rb”

concat is working ok.

expand_path doesn’t simply concatenate. If it did, we could
simply do dir + name.

ruby -e ‘p File.expand_path(“a/b”)’
“/tmp/a/b”
ls a
ls: a: No such file or directory

Taking a valid relative pathname and returning an invalid
absolute pathname is not useful, certainly not a feature.

If not a bug, at least an anomaly.

I think concat are the desired behavier of expand_path.
For instance if you want to create a directory, you first
have to make the path, before you make it. I don’t have
better evidence.

···

Hal Fulton hal9000@hypermetrics.com wrote:


Simon Strandgaard

Simon Strandgaard wrote:

I think concat are the desired behavier of expand_path.
For instance if you want to create a directory, you first
have to make the path, before you make it. I don’t have
better evidence.

I see your point, and I don’t have a counterexample.

And I guess there is a problem with what the OP wanted –
if the original name is relative to the original current
directory, then the interpreter would have to keep track
of where we were relative to our original dir.

It is doable, but is it worth it? And is there a real
purpose to expand_path besides tilde substitution and
simple concatenation?

Matz??

Hal

Maybe extend FILE with a #absolute method,
in order to make FILE immune against chdir ?

···

Hal Fulton hal9000@hypermetrics.com wrote:

Simon Strandgaard wrote:

I think concat are the desired behavier of expand_path.
For instance if you want to create a directory, you first
have to make the path, before you make it. I don’t have
better evidence.

I see your point, and I don’t have a counterexample.

And I guess there is a problem with what the OP wanted –
if the original name is relative to the original current
directory, then the interpreter would have to keep track
of where we were relative to our original dir.

It is doable, but is it worth it? And is there a real
purpose to expand_path besides tilde substitution and
simple concatenation?


Simon Strandgaard

It does more than simple concatenation + ~ subst., it concatenates &
normalizes:

Dir.pwd

=>“/tmp”

File.expand_path “…/bin/sh”

=>“/bin/sh”

not => “/tmp/…/bin/sh”

···

On Fri, Apr 30, 2004 at 09:23:53AM +0900, Hal Fulton wrote:

And I guess there is a problem with what the OP wanted –
if the original name is relative to the original current
directory, then the interpreter would have to keep track
of where we were relative to our original dir.

It is doable, but is it worth it? And is there a real
purpose to expand_path besides tilde substitution and
simple concatenation?


Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

“You, sir, are nothing but a pathetically lame salesdroid!
I fart in your general direction!”
– Randseed on #Linux

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:20040430022720.4b2c5b05.neoneye@adslhome.dk…

Simon Strandgaard wrote:

I think concat are the desired behavier of expand_path.
For instance if you want to create a directory, you first
have to make the path, before you make it. I don’t have
better evidence.

I see your point, and I don’t have a counterexample.

And I guess there is a problem with what the OP wanted –
if the original name is relative to the original current
directory, then the interpreter would have to keep track
of where we were relative to our original dir.

It is doable, but is it worth it? And is there a real
purpose to expand_path besides tilde substitution and
simple concatenation?

Maybe extend FILE with a #absolute method,
in order to make FILE immune against chdir ?

This is easily fixed:

09:58:20 [ruby]: /cygdrive/c/temp/ruby/pfile.rb
[“/cygdrive/c/temp/ruby/pfile.rb”, “/cygdrive/c/temp/ruby/pfile.rb”]
09:58:31 [ruby]: ./pfile.rb
[“./pfile.rb”, “/cygdrive/c/temp/ruby/pfile.rb”]
09:58:38 [ruby]: ruby pfile.rb
[“pfile.rb”, “/cygdrive/c/temp/ruby/pfile.rb”]
09:58:40 [ruby]: cat pfile.rb
#!/usr/bin/ruby

FILE = File.expand_path FILE

p [FILE, FILE]

Regards

robert
···

Hal Fulton hal9000@hypermetrics.com wrote:

Not if the person has done a chdir just before expand_path.
I wonder why FILE isn’t an absolute path. Relative paths is
just too fragile.

Proposal: make FILE an absolute path.
That would make FILE robust to Dir.chdir.

Any thoughts on this proposal? fore or against

···

“Robert Klemme” bob.news@gmx.net wrote:

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Maybe extend FILE with a #absolute method,
in order to make FILE immune against chdir ?

This is easily fixed:

FILE = File.expand_path FILE
p [FILE, FILE]


Simon

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:20040430124420.2f2b621b.neoneye@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Maybe extend FILE with a #absolute method,
in order to make FILE immune against chdir ?

This is easily fixed:

FILE = File.expand_path FILE
p [FILE, FILE]

Not if the person has done a chdir just before expand_path.

Well, I should’ve written “first line in script”.

I wonder why FILE isn’t an absolute path. Relative paths is
just too fragile.

Proposal: make FILE an absolute path.
That would make FILE robust to Dir.chdir.

Any thoughts on this proposal? fore or against

Slightly against, because

  • it’s easily fixed

  • you loose information: there might be situations where the script wants
    to know the exact path it was invoked with.

  • most of the time (when invoked from the shell via path expansion)
    scripts are invoked with an absolute path anyway.

Kind regards

robert
···

“Robert Klemme” bob.news@gmx.net wrote:

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:20040430124420.2f2b621b.neoneye@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Maybe extend FILE with a #absolute method,
in order to make FILE immune against chdir ?

This is easily fixed:

FILE = File.expand_path FILE
p [FILE, FILE]

Not if the person has done a chdir just before expand_path.

Well, I should’ve written “first line in script”.

ok :wink:

I wonder why FILE isn’t an absolute path. Relative paths is
just too fragile.

Proposal: make FILE an absolute path.
That would make FILE robust to Dir.chdir.

Any thoughts on this proposal? fore or against

Slightly against, because

  • it’s easily fixed

Agree… however see below

  • you loose information: there might be situations where the script wants
    to know the exact path it was invoked with.

I think its the wrong place to retrive this kind of information.
Broken metaphor… I have used it myself, but without thinking about it.

  • most of the time (when invoked from the shell via path expansion)
    scripts are invoked with an absolute path anyway.

Please elaborate… I don’t understand.

:slight_smile:

···

“Robert Klemme” bob.news@gmx.net wrote:

“Robert Klemme” bob.news@gmx.net wrote:


Simon Strandgaard

The OP yawns and wakes up to a big thread that has sprouted up where he
posted his little codeling…

I wonder why FILE isn’t an absolute path. Relative paths is
just too fragile.

Proposal: make FILE an absolute path.
That would make FILE robust to Dir.chdir.

Any thoughts on this proposal? fore or against

That was my expectation. I really don’t understand why FILE would
be relative. I did a lot of work in PHP before coming to Ruby, and PHP
uses an absolute path in its FILE, which is a wonderful thing when
trying to create programs that are robust against odd web server
configurations.

I see Perl uses relative paths for both FILE and $0…and since a
lot of Ruby scripts use “if FILE == $0”, those two should keep
following the same policy. So I don’t expect that behavior to change
for my odd little case.

Might there be another place to put this absolute path? (Or might one
exist already?) PHP defines a global $SCRIPT_FILENAME…

Slightly against, because

  • it’s easily fixed

but obviously from the head-scratching on this thread, the current
behavior at least threatens POLS.

  • you loose information: there might be situations where the script
    wants
    to know the exact path it was invoked with.

That seems like more of a special case to me than knowing exactly where
we live in the filesystem, but I’ll admit that if Ruby got this far
with this behavior, maybe I’m not in the majority.

  • most of the time (when invoked from the shell via path expansion)
    scripts are invoked with an absolute path anyway.

My situation: I was invoking a utility script from Vim’s shell, and it
had a bug that dumped output in the wrong directory. As I hacked a fix,
somehow I wound up with code that triggered the unexpected behavior I
posted about (I apologize for not pointing out which part was
unexpected).

Whatever the solution, I want it to be easy to get an authoritative
absolute path for the current file from Ruby; I’d strongly prefer that
it not be fragile to chdirs, since that’s a side effect that reduces
flexibility.

Surely there’s an existing solution to this within Ruby or Perl or some
other language?

Thanks to the other posters for the workaround(s) and explanation.

···

On 2004 Apr 30, at 6:39, Robert Klemme wrote:


Ryan “John” Platte
Custom services, NIKA Consulting
http://nikaconsulting.com/

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:20040430134446.7d4d3fc1.neoneye@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:20040430124420.2f2b621b.neoneye@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Maybe extend FILE with a #absolute method,
in order to make FILE immune against chdir ?

This is easily fixed:

FILE = File.expand_path FILE
p [FILE, FILE]

Not if the person has done a chdir just before expand_path.

Well, I should’ve written “first line in script”.

ok :wink:

I wonder why FILE isn’t an absolute path. Relative paths is
just too fragile.

Proposal: make FILE an absolute path.
That would make FILE robust to Dir.chdir.

Any thoughts on this proposal? fore or against

Slightly against, because

  • it’s easily fixed

Agree… however see below

  • you loose information: there might be situations where the script
    wants
    to know the exact path it was invoked with.

I think its the wrong place to retrive this kind of information.
Broken metaphor… I have used it myself, but without thinking about it.

Where would you expect it to reside? Maybe the best solution is

$0 : path as used for invocation
FILE: abs path to current file

Then I agree. :slight_smile: Any objections? Does this break existing code?

  • most of the time (when invoked from the shell via path expansion)
    scripts are invoked with an absolute path anyway.

Please elaborate… I don’t understand.

:slight_smile:

15:35:31 [ContentReporter_BRANCH]: PATH=“${PATH}:/c/temp/ruby” bash -c
‘echo $PATH; dollar0.rb’
:/c/temp/ruby
__FILE=/c/temp/ruby/dollar0.rb
$0=/c/temp/ruby/dollar0.rb
15:35:51 [ContentReporter_BRANCH]: cat /c/temp/ruby/dollar0.rb
#!/usr/bin/ruby

puts “__FILE=#{FILE}”
puts “$0=#{$0}”

The invocation (-c ‘dollar0.rb’) does not use a path but rather the shell
finds the executable based on its $PATH.

Regards

robert
···

“Robert Klemme” bob.news@gmx.net wrote:

“Robert Klemme” bob.news@gmx.net wrote:

“John Platte” john.platte@nikaconsulting.com schrieb im Newsbeitrag
news:81CD2517-9AB0-11D8-82AE-000A95EB0812@nikaconsulting.com

The OP yawns and wakes up to a big thread that has sprouted up where he
posted his little codeling…

I wonder why FILE isn’t an absolute path. Relative paths is
just too fragile.

Proposal: make FILE an absolute path.
That would make FILE robust to Dir.chdir.

Any thoughts on this proposal? fore or against

That was my expectation. I really don’t understand why FILE would
be relative. I did a lot of work in PHP before coming to Ruby, and PHP
uses an absolute path in its FILE, which is a wonderful thing when
trying to create programs that are robust against odd web server
configurations.

I see Perl uses relative paths for both FILE and $0…and since a
lot of Ruby scripts use “if FILE == $0”, those two should keep
following the same policy. So I don’t expect that behavior to change
for my odd little case.

… or operators are overloaded to ensure proper behavior.

Might there be another place to put this absolute path? (Or might one
exist already?) PHP defines a global $SCRIPT_FILENAME…

Slightly against, because

  • it’s easily fixed

but obviously from the head-scratching on this thread, the current
behavior at least threatens POLS.

  • you loose information: there might be situations where the script
    wants
    to know the exact path it was invoked with.

That seems like more of a special case to me than knowing exactly where
we live in the filesystem, but I’ll admit that if Ruby got this far
with this behavior, maybe I’m not in the majority.

Both may be true. :slight_smile:

  • most of the time (when invoked from the shell via path expansion)
    scripts are invoked with an absolute path anyway.

My situation: I was invoking a utility script from Vim’s shell, and it
had a bug that dumped output in the wrong directory. As I hacked a fix,
somehow I wound up with code that triggered the unexpected behavior I
posted about (I apologize for not pointing out which part was
unexpected).

Whatever the solution, I want it to be easy to get an authoritative
absolute path for the current file from Ruby; I’d strongly prefer that
it not be fragile to chdirs, since that’s a side effect that reduces
flexibility.

Surely there’s an existing solution to this within Ruby or Perl or some
other language?

See my other post:

at the top of script

FILE = File.expand_path( __FILE __ )

Thanks to the other posters for the workaround(s) and explanation.

We love to bang our heads on simple looking but difficult to solve
problems. :slight_smile:

robert
···

On 2004 Apr 30, at 6:39, Robert Klemme wrote:

Robert Klemme wrote:

Where would you expect it to reside? Maybe the best solution is

$0 : path as used for invocation
FILE: abs path to current file

Then I agree. :slight_smile: Any objections? Does this break existing code?

Wouldn’t this break the idiom of using

if FILE == $0 then
#…
end

to make a file both require-able and executable?
I know I use it frequently.

···


([ Kent Dahl ]/)_ ~ [ http://www.pvv.org/~kentda/ ]/~
))_student_/(( _d L b_/ Master of Science in Technology )
( __õ|õ// ) ) Industrial economics and technology management (
_
/ö____/ (_engineering.discipline=Computer::Technology)

I see Perl uses relative paths for both FILE and $0…and since a
lot of Ruby scripts use “if FILE == $0”, those two should keep
following the same policy. So I don’t expect that behavior to change
for my odd little case.

… or operators are overloaded to ensure proper behavior.

I can’t imagine that would lead to increased predictability!

On this topic, however, it’d be nice to have a method like
this_file_invoked? that encapsulated the $0 == FILE idiom.

Surely there’s an existing solution to this within Ruby or Perl or
some
other language?

See my other post:

at the top of script

FILE = File.expand_path( __FILE __ )

Yes, that snippet was a workaround I was thanking you for, but I don’t
consider it a solution to the problem:

it seems we can’t determine the absolute path of FILE correctly
after a chdir without having planned for that eventuality before the
chdir.

Can someone solve that one?

···

On 2004 Apr 30, at 9:39, Robert Klemme wrote:


Ryan “John” Platte
Custom services, NIKA Consulting
http://nikaconsulting.com/

“Kent Dahl” kentda+news@stud.ntnu.no schrieb im Newsbeitrag
news:c6tmj9$58n$1@orkan.itea.ntnu.no…

Robert Klemme wrote:

Where would you expect it to reside? Maybe the best solution is

$0 : path as used for invocation
FILE: abs path to current file

Then I agree. :slight_smile: Any objections? Does this break existing code?

Wouldn’t this break the idiom of using

if FILE == $0 then
#…
end

to make a file both require-able and executable?
I know I use it frequently.

Yeah, I think it is used quite frequently. Darn. The only ad hoc
sulution to this that occurs to me is to override FILE#== and $0#== to
repair this. Now this starts getting ugly… Simon?

robert

what’s wrong with this, i do it in all my programs:

require ‘pathname’

class Main

FILE = Pathname.new(FILE).realpath.to_s

end

what’s wrong with solving it by planning for it?

-a

···

On Fri, 30 Apr 2004, John Platte wrote:

On 2004 Apr 30, at 9:39, Robert Klemme wrote:

I see Perl uses relative paths for both FILE and $0…and since a
lot of Ruby scripts use “if FILE == $0”, those two should keep
following the same policy. So I don’t expect that behavior to change
for my odd little case.

… or operators are overloaded to ensure proper behavior.

I can’t imagine that would lead to increased predictability!

On this topic, however, it’d be nice to have a method like
this_file_invoked? that encapsulated the $0 == FILE idiom.

Surely there’s an existing solution to this within Ruby or Perl or
some
other language?

See my other post:

at the top of script

FILE = File.expand_path( __FILE __ )

Yes, that snippet was a workaround I was thanking you for, but I don’t
consider it a solution to the problem:

it seems we can’t determine the absolute path of FILE correctly
after a chdir without having planned for that eventuality before the
chdir.

Can someone solve that one?

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================