File.basename bug?


#1

How often do people get bitten by this?
When operating on a file in the current directory, ‘./’ must be
prepended to a filename for File.basename to work…

or is this unexpected behavior?

$ cat bug.rb
DATAFORMAT_VERSION=1

def processInputFile(inputFpath)
puts “inputFpath #{inputFpath}”
dirpath = File.dirname(inputFpath)

outputfile = File.basename(inputFpath)
outputfile.gsub!("pp_",'')
outputfile = dirpath + '/' + 'SDF_' + "#{DATAFORMAT_VERSION}" + '_' 
  • outputfile
    puts “outputfile #{outputfile}”
    puts “inputFpath #{inputFpath}”

end

processInputFile(“pp_a_test_file_name”)
rthompso@raker>/home/rthompso
$ ruby bug.rb
inputFpath pp_a_test_file_name
outputfile ./SDF_1_a_test_file_name
inputFpath a_test_file_name
rthompso@raker>/home/rthompso
$ ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-linux]

rthompso@raker>/home/rthompso
$ vi bug.rb
rthompso@raker>/home/rthompso
$ ruby bug.rb
inputFpath /home/rthompso/pp_a_test_file_name
outputfile /home/rthompso/SDF_1_a_test_file_name
inputFpath /home/rthompso/pp_a_test_file_name


#2

On Mon, May 11, 2009 at 9:14 PM, Reid T. removed_email_address@domain.invalid
wrote:

How often do people get bitten by this?
When operating on a file in the current directory, ‘./’ must be
prepended to a filename for File.basename to work…

Hi, i’m either not understanding your issue or not seeing it on my box:

$: cd /tmp; touch by.touch

$: ruby19 -ve “puts File.basename ‘by.touch’”
ruby 1.9.1p0 (2009-01-30) [i386-darwin8.11.1]
by.touch

$: ruby -ve “puts File.basename ‘by.touch’”
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin8]
by.touch

puts “outputfile #{outputfile}”
rthompso@raker>/home/rthompso
$ ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-linux]

rthompso@raker>/home/rthompso
$ vi bug.rb
rthompso@raker>/home/rthompso
$ ruby bug.rb
inputFpath /home/rthompso/pp_a_test_file_name
outputfile /home/rthompso/SDF_1_a_test_file_name
inputFpath /home/rthompso/pp_a_test_file_name

Scanned over the above but couldn’t spot what you might be on about :slight_smile:
Perhaps you could clarify or wittle the example down a bit further?

cheers,
lasitha


#3

On Tue, 2009-05-12 at 03:10 +0900, lasitha wrote:

ruby 1.9.1p0 (2009-01-30) [i386-darwin8.11.1]

puts “inputFpath #{inputFpath}”
processInputFile(“pp_a_test_file_name”)
$ vi bug.rb
lasitha

example 1 -> processInputFile(“pp_a_test_file_name”)
“pp_a_test_file_name” is a string object
File.basename sets outputfile to the same object as
“pp_a_test_file_name”.
as a result the gsub! action on outputfile acts on the
“pp_a_test_file_name” object.

example 2 -> processInputFile("./pp_a_test_file_name")
“./pp_a_test_file_name” is a string object
File.basename sets outputfile to a new object as “pp_a_test_file_name”.
as a result the gsub! action on outputfile acts on the new object,
without modifying the original “./pp_a_test_file_name”


#4

On 11.05.2009 20:21, Reid T. wrote:

ruby 1.9.1p0 (2009-01-30) [i386-darwin8.11.1]

puts “inputFpath #{inputFpath}”
processInputFile(“pp_a_test_file_name”)
$ vi bug.rb

File.basename sets outputfile to a new object as “pp_a_test_file_name”.
as a result the gsub! action on outputfile acts on the new object,
without modifying the original “./pp_a_test_file_name”

Heureka! It’s an aliasing problem which is not there in 1.9:

$ irb19
irb(main):001:0> s = ‘foo.txt’
=> “foo.txt”
irb(main):002:0> x = File.basename s
=> “foo.txt”
irb(main):003:0> s.equal? x
=> false
irb(main):004:0> s.object_id
=> 134667930
irb(main):005:0> x.object_id
=> 134637100
irb(main):006:0>

$ irb
irb(main):001:0> s = ‘foo’
=> “foo”
irb(main):002:0> x = File.basename s
=> “foo”
irb(main):003:0> s.equal? x
=> true
irb(main):004:0> s.object_id
=> 1073538940
irb(main):005:0> x.object_id
=> 1073538940
irb(main):006:0>

Whether you consider this actually a bug of File.basename - I don’t
know. It is at least a documentation bug because the docs do not
mention that fact.

Kind regards

robert


#5

On 11.05.2009 20:10, lasitha wrote:

ruby 1.9.1p0 (2009-01-30) [i386-darwin8.11.1]

puts “inputFpath #{inputFpath}”
dirpath = File.dirname(inputFpath)

outputfile = File.basename(inputFpath)

This can be combined as

dir, out = File.split input_path

inputFpath pp_a_test_file_name
outputfile ./SDF_1_a_test_file_name
inputFpath a_test_file_name

This output cannot come from the code above as “inputFpath” does not
change in the method.

inputFpath /home/rthompso/pp_a_test_file_name

Scanned over the above but couldn’t spot what you might be on about :slight_smile:
Perhaps you could clarify or wittle the example down a bit further?

I am assuming that not all tests were done with the same version of the
code and this might have led to confusion. :slight_smile:

Kind regards

robert


#6

On Tue, 2009-05-12 at 03:30 +0900, Robert K. wrote:

$: ruby19 -ve “puts File.basename ‘by.touch’”

def processInputFile(inputFpath)
outputfile = dirpath + ‘/’ + ‘SDF_’ + “#{DATAFORMAT_VERSION}” + ‘_’ + outputfile
inputFpath a_test_file_name

This output cannot come from the code above as “inputFpath” does not
change in the method.
Not sure what you mean – this output did come from the above code.
inputFpath is modified by the gsub! call on outputfile

rthompso@raker>/home/rthompso
$ irb
irb(main):001:0> DATAFORMAT_VERSION=1
=> 1
irb(main):002:0>
irb(main):003:0* def processInputFile(inputFpath)
irb(main):004:1> puts “inputFpath #{inputFpath}”
irb(main):005:1> dirpath = File.dirname(inputFpath)
irb(main):006:1>
irb(main):007:1* outputfile = File.basename(inputFpath)
irb(main):008:1> outputfile.gsub!(“pp_”,’’)
irb(main):009:1> outputfile = dirpath + ‘/’ + ‘SDF_’ +
“#{DATAFORMAT_VERSION}” + ‘_’ + outputfile
irb(main):010:1> puts “outputfile #{outputfile}”
irb(main):011:1> puts “inputFpath #{inputFpath}”
irb(main):012:1>
irb(main):013:1* end
=> nil
irb(main):014:0>
irb(main):015:0* processInputFile(“pp_a_test_file_name”)
inputFpath pp_a_test_file_name
outputfile ./SDF_1_a_test_file_name
inputFpath a_test_file_name
=> nil


#7

On 11.05.2009 21:33, Reid T. wrote:

On Tue, 2009-05-12 at 03:30 +0900, Robert K. wrote:

This output cannot come from the code above as “inputFpath” does not
change in the method.
Not sure what you mean – this output did come from the above code.
inputFpath is modified by the gsub! call on outputfile

You are right. It’s an aliasing problem not present in 1.9.1 which I am
using. See my other posting.

Kind regards

robert