Forum: Ruby Newbie: need suggestion for "the ruby way"

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.
kiol (Guest)
on 2006-02-21 02:41
(Received via mailing list)
I write some code for generate file index for a directory.like this:
#!/usr/local/bin/ruby

def parse_options(args)
  require 'optparse'
  require 'ostruct'

  options = OpenStruct.new
  opts = OptionParser.new("Usage: genindex [options] paths")
  options.dirs = []
  opts.on_tail("-h", "--help", "Show this message") do
    puts opts
    exit
  end
  opts.on_tail("-v", "--version", "Show version") do
    require '../version'
    puts Version.join('.')
    exit
  end
  rest = opts.parse(args)
  if rest.empty?:
    puts opts
  else
    rest.each {|dir| options.dirs.push(Dir.new(File.expand_path(dir)))}
  end
  if $DEBUG
    puts "get params:"
    options.dirs.each {|dir| puts dir.path}
    puts "end"
  end
  options
end

def get_indexs(curdir, indexs)
  puts 'indexing ', curdir.path if $DEBUG
  curdir.each do |f|
    next if ['.svn', '.', '..'].include?(f)
    if File.directory?(File.join(curdir.path,f))
      get_indexs(Dir.new(File.join(curdir.path,f)), indexs)
    else
      #it's case insensitive
      indexs[f.downcase] ||= []
      indexs[f.downcase] += [File.join(curdir.path, f)]
    end
  end
end

def create_idx_file(options)
  data_dir = File.join(File.dirname(File.expand_path(__FILE__)), '..',
'data')
  Dir.mkdir(data_dir) if not File.exist?(data_dir)
  Dir.chdir(data_dir) do
    options.dirs.each do |dir|
      d = dir.path.split(File::SEPARATOR).join('_')
      next if Dir.foreach('.') do |idxdir|
        next if ['.', '..', '.svn'].include?(idxdir)
        #sub dir need be ingored but same dir need recreate
        if d != idxdir and d.index(idxdir) == 0
          puts "path #{File.join(d.split('_'))} is ingored."
          puts "Because it's ancestors path
#{File.join(idxdir.split('_'))} already been indexed."
          break true
        end
      end

      Dir.mkdir(d) if not File.exist?(d)
      Dir.chdir(d) do
        File.open('indexs.yaml', 'w') do |idx_file|
          require 'yaml'
          indexs = {}
          get_indexs(dir, indexs)
          YAML.dump(indexs, idx_file)
        end
      end
    end
  end
end

if $0 == __FILE__
  begin
    create_idx_file(parse_options(ARGV))
  rescue Exception => e
    puts e.to_s
  end
end
and the test code is :
#!/usr/local/bin/ruby
$:.unshift(File.join(File.dirname(__FILE__),"..", "lib"))

require 'test/unit'
require 'genindex'
require 'optparse'

class TextGenIndex < Test::Unit::TestCase
  def test_option_parse
    args = ["."]
    assert_equal(File.expand_path("."),
parse_options(args).dirs[0].path)
    args = ['..']
    assert_equal(File.expand_path(".."),
parse_options(args).dirs[0].path)
    args = ["-sdf"]
    assert_raise(OptionParser::InvalidOption) {parse_options(args)}
    args = ["/var","/tmp"]
    assert_equal("/var", parse_options(args).dirs[0].path)
    assert_equal("/tmp", parse_options(args).dirs[1].path)
  end
  def test_create_idx_file
    data_dir = File.join(File.dirname(File.expand_path(__FILE__)),
'..', 'data')
    args = ['.']
    create_idx_file(parse_options(args))
    assert_equal(File.exist?(data_dir), true)
    index_dir = File.join(File.dirname(File.expand_path(__FILE__)),
'..', 'data', File.expand_path('.').split(File::SEPARATOR).join('_'))
    assert_equal(File.exist?(index_dir), true)
    args = ['lib', 'test']
    create_idx_file(parse_options(args))
    assert_equal(File.exist?(File.join(data_dir,
data_dir.split(File::SEPARATOR)[0..-4].push('lib').join('_'))), false)
    require 'yaml'
    index_file = File.join(index_dir, 'indexs.yaml')
    indexs = YAML.load(File.open(index_file))
    assert_equal(indexs['version.rb'.downcase][0],
File.join(data_dir.split(File::SEPARATOR)[0..-4], 'version.rb'))
  end
end

I need some help for going to "the ruby way".
this my first question on the group and I must apologize for my poor
english and thanks a lot for your suggestion for my ruby code or my
english.
So, any suggestion is wellcome.
Joby B. (Guest)
on 2006-02-21 20:09
(Received via mailing list)
It might be more helpful to show what kind of output you want, rather
than what code you've created.

However, for a simple recursive directory listing, look more into the
Dir object:

depth = 1 #current or one directory down
files = Dir['**/*'].reject {|item|
	#filter out directories and directory depth
	File.directory?(item) or File.dirname(item).split('/').size > depth
}
puts files

You can add more logic to filter out other files, organize them in a
tree-like structure, etc.  But, the Dir object and methods are VERY
useful when used with File and other common Array and String methods.
kiol (Guest)
on 2006-02-22 07:15
(Received via mailing list)
thanks a lot.
I just want to index the files and only files in some directory.
like this:
dir_a/dir_b/file_c
dir_a/file_d
will indexed as
file_c->dir_a/dir_b/file_c
file_d->dir_a/file_d
and dump this with YAML.

Now I think I can do that like this:
      Dir.chdir(d) do
        File.open('indexs.yaml', 'w') do |idx_file|
          require 'yaml'
          indexs = {}
          Dir.chdir(dir.path) do
            Dir['**/*'].reject {|item| File.directory?(item)}
          end
          YAML.dump(indexs, idx_file)
        end
      end

so I do't need the recursive procudure.
Robert K. (Guest)
on 2006-02-22 12:24
(Received via mailing list)
2006/2/21, Joby B. <removed_email_address@domain.invalid>:
> }
> puts files
>
> You can add more logic to filter out other files, organize them in a
> tree-like structure, etc.  But, the Dir object and methods are VERY
> useful when used with File and other common Array and String methods.

Not that there is module Find which has recursion built in:

require 'find'
Find.find('.') {|f| puts f}

Kind regards

robert
kiol (Guest)
on 2006-02-23 02:35
(Received via mailing list)
yes, this is what i want.
thanks very much.
This topic is locked and can not be replied to.