Strangeness in Find.find

I was just looking at lib/ruby/1.8/find.rb and I am stumped by the marked
line:

def find(*paths) # :yield: path
paths.collect!{|d| d.dup} # << ?!
while file = paths.shift
… etc

For each element of the ‘paths’ array, it is duplicating that entry, then
collecting those duplicates into a new array, and then immediately throwing
away that array!

It also exists in 1.6 except the variable is called ‘path’ not ‘paths’

Does this line have a useful side-effect that I can’t see? Or was it
intended to be

paths = paths.collect{|d| d.dup}

Regards,

Brian.

Brian Candler wrote:

I was just looking at lib/ruby/1.8/find.rb and I am stumped by the marked
line:

def find(*paths) # :yield: path
paths.collect!{|d| d.dup} # << ?!
while file = paths.shift
… etc

For each element of the ‘paths’ array, it is duplicating that entry, then
collecting those duplicates into a new array,

I do not think it makes a new array. It uses the same array object.
Notice the “!”.

and then immediately throwing
away that array!

No. It reuses the array object created upon calling it, which probably
saves both space and time. As for why the dup-ing is necessary, I don’t
know.

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

self.doh!

In that case though, I can’t see why it is taking dup copies of the
elements: it passes them to File.lstat, Dir.open and File.join, but I don’t
think any of those modify their string arguments.

Regards,

Brian.

···

On Sat, Apr 05, 2003 at 08:43:17PM +0900, Kent Dahl wrote:

def find(*paths) # :yield: path
paths.collect!{|d| d.dup} # << ?!
while file = paths.shift
… etc

For each element of the ‘paths’ array, it is duplicating that entry, then
collecting those duplicates into a new array,

I do not think it makes a new array. It uses the same array object.
Notice the “!”.

Brian Candler wrote:

In that case though, I can’t see why it is taking dup copies of the
elements: it passes them to File.lstat, Dir.open and File.join, but I don’t
think any of those modify their string arguments.

Perhaps not, but what about when it is used with a block, into which the
elements are yielded? The block might call modifying methods on the
strings or objects given. Of course, that will usually be in the same
scope as the method is called, so it would seem rather obvious, but once
you start using Proc objects, it can be a nightmare understanding why
your string objects are shapeshifting on you.

Just my 0.02 NOK…

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

Yep, good point. It could have done

  yield file.dup

but that would give unnecessary duplication where the filename was generated
from a directory expansion.

Thanks for the insight…

Brian.

···

On Sat, Apr 05, 2003 at 09:03:25PM +0900, Kent Dahl wrote:

Brian Candler wrote:

In that case though, I can’t see why it is taking dup copies of the
elements: it passes them to File.lstat, Dir.open and File.join, but I don’t
think any of those modify their string arguments.

Perhaps not, but what about when it is used with a block, into which the
elements are yielded? The block might call modifying methods on the
strings or objects given.