Being able to read the source of the executing program enables a neat ‘usage’ trick.
Well-behaved command line programs (remember the command line?) display a nice usage message when given invalid arguments. The message describes what they do and how they should be invoked. Well-documented command line programs also start with some kind of comment block. The comment describes what they do and how they should be invoked.
Hmmm, seems like a violation of the DRY principle, having all that information duplicated…
In Ruby (and most scripting languages, I suspect) it needn’t be. Let’s
assume that the top-level source file in your application starts with
a comment describing how it is used. We can then use the
built-in caller
method, which returns call stack. The last element in
this array is the top level program. The entry is in the
form filename:linenumber, so we can use a simple regexp to extract
just the file name portion. We then open that source file and read in
the comment block, writing it out as a help message after stripping
the leading comment characters.
The show_usage method is pretty simple:
def show_usage(msg=nil)
name = caller[-1].sub(/:\d+$/, '')
$stderr.puts "\nError: #{msg}" if msg
$stderr.puts
File.open(name) do |f|
while line = f.readline and line.sub!(/^# ?/, '')
$stderr.puts line
end
end
exit 1
end
An example of this method in use is the start of a simple utility I wrote to record ad-hoc royalty payments to authors.
# Pay an author a sum of money. We simply record the payment
# in the author_royalty_payment table: the statement code
# sorts it all out
#
# usage:
# ruby pay.rb "Author Name" 1234.56 <checkno>
#
require "common"
author = ARGV.shift || show_usage("Missing author name")
amount = ARGV.shift || show_usage("Missing amount")
amount = Money(amount) rescue show_usage("Invalid amount")
check = ARGV.shift || show_usage("Missing check")
Trivial, I know, but I like the simplicity.
- NickName, E-Mail, and Website are optional. If you supply an e-mail, we'll notify you of activity on this thread.
- You can use Markdown in your comment (and preview it using the magnifying glass icon in the bottom toolbar).