From: John Johnson Date: 2006-04-20T01:18:26+09:00 Subject: Re: practices (File and directory structure) If the safe mode is a problem, do all your require'ing before changing the safe mode (I think). You might also have an unsafe program that does the require'ing, then includes and runs the safe part. For non-trivial programs, I have begun using a structure as follows. I picked up the bin/ doc/ test/ somewhere (thanks whomever you are), but can't remember where, and added to it. labeler/ bin/ # "Binaries," i.e. files that are run directly lbl.rb config/ # config files. config.yaml label_defs.yaml data/ # Any data needed to setup/run the system doc/ # RDoc and other documentation classes files ... email-from-blah-blah.txt some-ref.pdf lib/ # rb's go here entity.rb label.rb ... release/ # Files needed to build a release build.rb # of the system go here. labeler-1.1.5.zip # zip created to send customer # *.zip is ignored by svn here. test/ # unit tests go here data/ # it would be better if my test data # were in a dir like this. currently # it's all just glommed into test/. tc_lbl.rb # tc_ = test case test_labeler.rb ... ts_labeler.rb # a test suite vendor/ extensions/ # my own extensions to Ruby core classes integer_ext.rb # adds #is_odd?, #is_even? regexp_ext.rb # adds #+ method. serial/ # a serial library vendor.rb # see below In my main program, bin/lbl.rb, I have the following: # Add ../lib and ../vendor to the load path. $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")) $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "vendor")) require 'vendor' require 'optparse' ... require 'label_printer' ... # Location of the config file. CONFIG_FILE = File.join(File.dirname(__FILE__), "..", "config", "config.yaml") ... config = YAML.load_file(filename) # load the config data ... #################### vendor/vendor.rb is the following: #!/usr/bin/env ruby # # vendor # # Created by John Johnson on 2006-03-31. # Copyright (c) 2006 John Johnson Software, LLC, All rights reserved. # # Prepend all vendor subdirectories to the load path. # dir=Dir.new(File.dirname(__FILE__)) dir = dir.to_a not_dots = dir.delete_if { |d| d =~ /^\./ } not_files = not_dots.delete_if { |d| to_check = File.join(File.dirname(__FILE__), d) File.file?(to_check) } not_files.each { |a_dir| to_add = File.join(File.dirname(__FILE__), a_dir) to_add = File.expand_path(to_add) $:.unshift to_add } Which prepends all subdirectories of vendor onto the load path. ################### I added an option to the main program (--test) that will run all the unit tests: opts = OptionParser.new ... opts.on("--test", "Run unit tests on this program.") { Dir.chdir('test') system('ruby ts_labeler.rb') exit(1) } This is so the customer (or I) can do: lbl --test at my direction to test the system. ################ Since I deploy this system on Windows, I have the obligatory lbl.bat file in the system's root: @echo off rem Use OLD_PATH to keep paths found from accumulating in PATH. SET OLD_PATH=%PATH% rem Prefered path is last. IF EXIST c:\djgpp\bin\ruby.exe SET PATH=c:\djgpp\bin;%OLD_PATH% IF EXIST c:\usr\local\bin\ruby.exe SET PATH=c:\usr\local\bin;%OLD_PATH% IF EXIST c:\ruby\bin\ruby.exe SET PATH=c:\ruby\bin;%OLD_PATH% ruby bin/%0.rb %* ################### All the above (files, dirs, data, etc.) is kept in an SVN repository. Everything in the vendor folder is external, meaning they are housed elsewhere, and brought into vendor on this system and others I write. For small systems or utilities for my own use, with a couple of files, I just put everything in one directory. As far as dividing classes into files, go with your gut. I put like things together. There is no need in having thirty'leven (colloquialism used in the Southeastern United States meaning 'a lot of', see also 'dollar two ninety eight') files just so each class is in it's own file. Writing the unit tests seems to help with deciding how to group things too. Unit testing also helps you divide functions and methods into manageable chunks. I highly recommend using Subversion and unit tests (if you couldn't tell). There is a learning curve, but both are indispensable. Hope this helps! Regards, JJ On 18-Apr-2006, at 20:17, Tom Allison wrote: > Is there anything of a best practices on how to use your own modules? > > I've been doing a LOT of this in perl and have just started to play > with it in Ruby. > > Some things I am transistioning from are: > use lib -- how do I specify an alternate location for files? > > modules/object/files: > It may be bad form to put more than on class in a single file, I know > it is in Perl. But is there a reason not to? I have some classes > that are very tightly related in inheritance and they are very small. > I don't see much advantage to ever physically breaking them apart. > > --- Help everyone. If you can't do that, then at least be nice.