Forum: Ruby File.basename bug?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
91e1fb8bd265b7629491ab64c42f0906?d=identicon&s=25 Reid Thompson (Guest)
on 2009-05-11 17:45
(Received via mailing list)
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
E16e84e861c1815ce11ba7bd851c857d?d=identicon&s=25 lasitha (Guest)
on 2009-05-11 20:11
(Received via mailing list)
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

>    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 :)
Perhaps you could clarify or wittle the example down a bit further?

cheers,
lasitha
91e1fb8bd265b7629491ab64c42f0906?d=identicon&s=25 Reid Thompson (Guest)
on 2009-05-11 20:22
(Received via mailing list)
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"
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-05-11 20:31
(Received via mailing list)
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 :)
> 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. :-)

Kind regards

  robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-05-11 20:45
(Received via mailing list)
On 11.05.2009 20:21, Reid Thompson 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
91e1fb8bd265b7629491ab64c42f0906?d=identicon&s=25 Reid Thompson (Guest)
on 2009-05-11 21:34
(Received via mailing list)
On Tue, 2009-05-12 at 03:30 +0900, Robert Klemme 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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-05-11 22:35
(Received via mailing list)
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

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
This topic is locked and can not be replied to.