Forum: Ruby Newb Wants to Better His File, Dir code

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.
R.B.Love (Guest)
on 2007-06-09 06:36
(Received via mailing list)
I've got code working to do what I want but I'm hoping there is a
better way.  Mine seems clumsy.

My goal is to search over all files,  identify all that are directories
and then do something to each directory.  I don't need to go into
directories recursively yet.

The fact that Dir.foreach returns strings seems odd to me.  All advice
appreciated.


#!/usr/local/bin/ruby

dpath = Dir.getwd

Dir.foreach(dpath) do
  |x|
  ddir = File.join(dpath,x)
  if File.directory?(ddir) && x != "." && x != ".." then
    puts %x{du -sh #{x}}
  end
end
rio4ruby (Guest)
on 2007-06-09 07:06
(Received via mailing list)
On Jun 8, 7:31 pm, R. B. Love <removed_email_address@domain.invalid> wrote:
> #!/usr/local/bin/ruby
>
> dpath = Dir.getwd
>
> Dir.foreach(dpath) do
>   |x|
>   ddir = File.join(dpath,x)
>   if File.directory?(ddir) && x != "." && x != ".." then
>     puts %x{du -sh #{x}}
>   end
> end

One way simplify your handling of files and directories is to use Rio.
This will require you to install a module that is not a part of the
standard Ruby distribution. The easiest way to do this is:
  gem install rio
(or on Unix or Linux: sudo gem install rio)

Then your code can be reduced to:

require 'rio'

rio.dirs do |x|
  puts %x{du -sh #{x}}
end
Michael T. Richter (Guest)
on 2007-06-09 07:31
(Received via mailing list)
On Sat, 2007-09-06 at 11:35 +0900, R.B.Love wrote:

>
> end
Try:


        dirs = Dir.entries(".").reject{|e| /\.{1,2}/ =~ e}.find_all{|e|
        File.directory? e}


At this point you have a list of directory names.  You can do whatever
you like to that list using .each(), .inject(), .collect(), etc.
Dan Z. (Guest)
on 2007-06-09 07:43
(Received via mailing list)
Michael T. Richter wrote:
>> appreciated.
>>     puts %x{du -sh #{x}}
>
> At this point you have a list of directory names.  You can do whatever
> you like to that list using .each(), .inject(), .collect(), etc.
>

The above has a small bug: it rejects all hidden directories. If you
want to block only ".." and ".", then change it to:

  dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
    File.directory? e}
rio4ruby (Guest)
on 2007-06-09 08:01
(Received via mailing list)
On Jun 8, 8:42 pm, Dan Z. <removed_email_address@domain.invalid> wrote:
> >> The fact that Dir.foreach returns strings seems odd to me.  All advice
> >>     puts %x{du -sh #{x}}
>
> The above has a small bug: it rejects all hidden directories. If you
> want to block only ".." and ".", then change it to:
>
>         dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
>                 File.directory? e}

This also has bug if you have a file name 'abc.'

Use rio.
Michael T. Richter (Guest)
on 2007-06-09 08:14
(Received via mailing list)
On Sat, 2007-09-06 at 12:42 +0900, Dan Z. wrote:

> >         dirs = Dir.entries(".").reject{|e| /\.{1,2}/ =~ e}.find_all{|e|
> >         File.directory? e}



> The above has a small bug: it rejects all hidden directories. If you
> want to block only ".." and ".", then change it to:



>   dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
>     File.directory? e}



Ah.  That is true.  I tested it in a directory that didn't have hidden
files or directories, so didn't note that.
Michael T. Richter (Guest)
on 2007-06-09 08:38
(Received via mailing list)
On Sat, 2007-09-06 at 13:00 +0900, rio4ruby wrote:

> >         dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
> >                 File.directory? e}



> This also has bug if you have a file name 'abc.'


There's bugs in most (all?) off-the-cuff code put up in mailing lists to
illustrate a point.  Yours (and the OP's) had the bug of not working on
directories with spaces in the name.


> Use rio.


http://snakeratpig.blogspot.com/2007/06/functional...
Florian Aßmann (Guest)
on 2007-06-09 11:31
(Received via mailing list)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi rbLove,

another solution is to delete the array items beforehand:

class Dir
   def self.dir_entries path, rejects = [ '.', '..' ]
     ( Dir.entries( path ) - rejects ).select { |entry|
File.directory? entry }
   end
end

=begin
irb(main):021:0> Dir.chdir '/tmp'
=> 0
irb(main):022:0> Dir.dir_entries '.'
=> [".X11-unix", "501"]
irb(main):023:0> Dir.dir_entries '.', []
=> [".", "..", ".X11-unix", "501"]
irb(main):024:0>
=end

This is the code I'm still using...

Sincereley
Florian

Am 09.06.2007 um 06:36 schrieb Michael T. Richter:

>
> http://snakeratpig.blogspot.com/2007/06/functional...
>
> --
> Michael T. Richter <removed_email_address@domain.invalid> (GoogleTalk:
> removed_email_address@domain.invalid)
> A well-designed and humane interface does not need to be split into
> beginner and expert subsystems. (Jef Raskin)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFGaldNl1R1ZNDW4WgRApPPAJ4/FVGxK7LXapjCAySUk7/FoyGP0QCfY6O2
a0a5NEcSS/etT88QZam2zHM=
=ImGP
-----END PGP SIGNATURE-----
Skye Shaw!@#$ (Guest)
on 2007-06-09 21:45
(Received via mailing list)
On Jun 8, 8:42 pm, Dan Z. <removed_email_address@domain.invalid> wrote:
> Michael T. Richter wrote:
> > On Sat, 2007-09-06 at 11:35 +0900, R.B.Love wrote:
>
> >> I've got code working to do what I want but I'm hoping there is a
> >> better way.  Mine seems clumsy.
>
> >> My goal is to search over all files,  identify all that are directories
> >> and then do something to each directory.  I don't need to go into
> >> directories recursively yet.

<snip OP's code>

>
>         dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
>                 File.directory? e}

If hidden directories are not important, maybe try:

[sshaw@localhost ~]$ ls -a
.              .emacs.d           .ICEauthority
.openoffice.org2.0
..             .esd_auth          images               .recently-used
addr.pl        .evolution         java                 ruby

<snip long listing>

ruby -le'Dir["/home/sshaw/*/"].each { |d| print d }'
/home/sshaw/video/
/home/sshaw/me/
/home/sshaw/ruby/
/home/sshaw/java/
/home/sshaw/dos-mundos/
/home/sshaw/cti/
/home/sshaw/wb/
/home/sshaw/images/
/home/sshaw/music/
/home/sshaw/Desktop/
/home/sshaw/GDMX/
/home/sshaw/mysql/
Adrian Challinor (Guest)
on 2007-06-12 10:46
(Received via mailing list)
rio4ruby wrote:
>>>> #!/usr/local/bin/ruby
>>>         File.directory? e}
> Use rio.
>

RIO is a great library. It is also a huge library to load for one simple
task. Though it has bugs in it, the author didn't claim that it was the
total solution nor that it didn't leave any holes - but the initial
comment from BB didn't ask for this - BB asked if the original code
worked or was "ugly".

Oh - and hats off to BB. A new person asking for advice on whether their
code is ugly is to be applauded.

What we would need to know is whether BB want to learn the best Ruby way
to do the directory search, or whether they want to do this as a
component in a much larger file processing application. If its the
former, then going with the pure Ruby code is good - and efficient. If
its the latter then RIO is an answer.

For me, the above solution would seem to be more in keeping with "The
Ruby Way".
Erik H. (Guest)
on 2007-06-12 12:57
(Received via mailing list)
On 2007-06-08 20:55:42 -0700, rio4ruby <removed_email_address@domain.invalid>
said:
>> File.directory? e}
>
> This also has bug if you have a file name 'abc.'
>
> Use rio.

Wouldn't changing the regex to read /^\.{1,2}$/ fix this problem?

Seems like a lot of unnecessary effort to complicate this code up with
an extra library to fix a regular expression.

-Erik
This topic is locked and can not be replied to.