File.basename bug?

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

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

$ 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

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

···

On Mon, May 11, 2009 at 9:14 PM, Reid Thompson <reid.thompson@ateb.com> wrote:

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"

···

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

On Mon, May 11, 2009 at 9:14 PM, Reid Thompson <reid.thompson@ateb.com> 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

> $ 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

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

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

$ cat bug.rb
DATAFORMAT_VERSION=1

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

   outputfile = File.basename(inputFpath)

This can be combined as

dir, out = File.split input_path

   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

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

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?

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

···

On 11.05.2009 20:10, lasitha wrote:

On Mon, May 11, 2009 at 9:14 PM, Reid Thompson <reid.thompson@ateb.com> wrote:

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

···

On 11.05.2009 20:21, Reid Thompson wrote:

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

On Mon, May 11, 2009 at 9:14 PM, Reid Thompson <reid.thompson@ateb.com> 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

$ 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

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

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"

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

>> 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
>
>> $ cat bug.rb
>> DATAFORMAT_VERSION=1
>>
>> def processInputFile(inputFpath)
>> puts "inputFpath #{inputFpath}"
>> dirpath = File.dirname(inputFpath)
>>
>> outputfile = File.basename(inputFpath)

This can be combined as

dir, out = File.split input_path

>> 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

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

···

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

On 11.05.2009 20:10, lasitha wrote:
> On Mon, May 11, 2009 at 9:14 PM, Reid Thompson <reid.thompson@ateb.com> wrote:

>> 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?

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

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

···

On 11.05.2009 21:33, Reid Thompson wrote:

On Tue, 2009-05-12 at 03:30 +0900, Robert Klemme 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