Andreas Schwarz wrote:
Graham Nicholls wrote:
OK, so its not a syntax error. Pedants
There ought to be a utility to
look for variable references, etc.
This is almost impossible in dynamic languages like ruby. Variables can
be defined everywhere, in eval(), conditional code, etc. You don't find
out until you execute it.
I had a feeling that this was the case.
> Now, I realize that this may be hard as
its presumably akin to part of writing a compile. What I'd like to know,
then is how to avoid the above - its a real nuisance in "scripting
languages" (Oh and if you don't like that term, get over it - you know
what I mean, python, perl(ugh!) Ruby & the like)
Use unit tests.
Could you elucidate. Typically this is pretty small stuff - my larger
projects tend to be coded in C, although unit testing can presumably be
applied there.
Heres a slice of code:
,----[ /home/graham/src/hsb/add_logo ]
#!/usr/bin/env ruby
#
=begin
Parse an input file (which is intended to be an Informix -produced text
file containing PCL escape sequences) for a pattern which will introduce a
logo. The pattern looks like this:
.LOGO filename x,y
where .LOGO (uppercase) is the special string, filename is the full path
to the logo file (/usr/local/logos?) and x and y are optional coordinates
for the logo which will otherwise be placed at the current file position.
Skeleton taken from ttp_merge.
The -c(onvert_euros) option from ttp_merge is kept, as when we move to
CUPS,this is a process which will need to be applied, as there is no
longer an interface file where we can do this.
G.Nicholls : 23 Aug 2004
=end
# globals:
$debug=false
$verbose=false
$convert_euros=false
$progname=$0
$ver=0.1
# Constants
USAGE_ERR=1
BAD_FILE=2
BAD_ARGS=3
MISC_ERROR=255
# "main" program
def main(argv)
output_fname = fname = nil
$progname.gsub!(/^.*\//,'') # Get rid of everything in path up to last /
argv.each do |arg|
case arg
when /-h(elp)?/
usage()
exit (0)
when /^-c(onvert)?(_euros)?/
$convert_euros=true
when /^-f(orce)?/
$force=true
when /^-v(erbose)?/
$verbose=true
printf("%s version %s\n",$0.sub(/^.*\//,""),$ver)
when /^-d/
print("DEBUG: Version #{$ver}\n")
$debug=true
when /^-o(\S+)/
output_fname=Regexp.last_match[1]
else
if fname != nil
usage("Sorry, you can only specify one file to merge")
exit(BAD_ARGS)
end
fname=arg
end
end
if fname == nil
usage("What file do you want me to logoise?\n")
exit(USAGE_ERR)
end
if output_fname == nil
output_fname=fname+".out"
end
if not $force
if FileTest::exists?(output_fname)
abort("Output file #{output_fname} exists already - use -f or -force to
overwrite it\n") end
end
if $verbose
print("#{$progname} : version #{$version} logoising file #{fname}\n")
print("Writing output to #{output_fname}\n")
if $force
print("which will be overwritten if it exists\n")
end
end
# OK process the file
begin
fdata=IO.readlines(fname)
rescue => err
abort("Error reading file #{fname} : #{err}\n",BAD_FILE)
end
# Match the pattern & an optional x,y part
logo_patt=Regexp.compile(/^\s*\.LOGO\s+(\S+)(\s+([0-9]+)\s*
\s*([0-9]+))?.*$/)
···
if $convert_euros
euro_patt=Regexp.compile(/([\$\~][\w\d]+):/)
end
line_no=0
fdata.each do |tline|
line_no+=1
if $debug
printf("Line %d: \n[%s]\n",line_no,tline)
end
# Before searching for a logo,FIRST replace euros if relevant,
# as there could be the euro char in the logo, where we do NOT want
# to replace it as it simply binary data:
if $convert_euros
line.tr!(\174,\244)
else
line.tr!(\234,\273)
end
#
# Search for the .LOGO lines
#
if (refs=logo_patt.match(tline)) != nil
logo_file=Regexp.last_match[1]
if $debug
printf("Found a logo : including [%s]\n",logo_file)
end
begin
# Insert the data from the include file
logo_data=IO.readlines(logo_file)
fdata=fdata[0..line_no-2] + logo_data + fdata[line_no..fdata.size()-1]
rescue =>err
printf("Error processing include file %s : %s\n",logo_file,err)
end
end
end
# OK, we now have an array with the merged data - write it:
opfile=File.new(output_fname,"w")
fdata.each do |tline|
opfile.puts("#{tline}")
end
opfile.close
end
def abort(message=nil,errcode=MISC_ERROR)
print message if message != nil
exit(errcode)
end
def usage(message=nil)
print message if message != nil
print("Usage: #{$progname} -v -d -h(elp) -o[output_fname] [filename]\n")
print("If output filename is not given, a suitable one will be
constructed\n") end
##########################################################################################
# OK, call main:
main(ARGV)
`----
As you can see, theres not much to it - an hours work or so - I'd rather not
have to spend much time writing testing - ISTM its easier to fix a bug when
it rears than spend ages trying to eliminate all possible bugs
Thanks
Graham
--
The answer's always "Yes". Now, what's the question?