Hello,
   As a newbie to Ruby, I've just written a program that uses Ruby for
caller ID services on a WinXP machine. It seems to work okay, but I come
from C/++, and wonder if I really did the program the way Ruby is
generally done. Any suggestions on making this more Ruby-like? In
particular, I'm still unsure about variable scoping rules. Does anyone
have a link to a document that explains Ruby variable scoping well?
Also, in Java or C#, the program logic is generally wrapped in a
class-is this also the way things are done in ruby, or is procedural
logic okay?

=========== cut ===========
#!/usr/bin/ruby -w

#########################################################
#
# log_CID.rb
#
# Ruby CID logging script
#
#    Logs all activity at a modem set to decipher CID
#    (Caller ID) information. Backs up weekly also.
#
##########################################################

require 'date'
require 'zip/zip'
require 'serialport/serialport.so'

############################################
#
# local settings here.
#
$backup_zip_filename = "CID_Data.zip"
modem_init_string = "AT+VCID=1\r\n" # for USR verbose CID output
backup_dir = "c:/modemlog"
base_log_name = "CID"
wday_to_backup = 7
hr_to_backup = 2
port_name = 'COM3:'
days_before_archive = 7
# const for backup intervals
ARCHIVE_DAYS_SECS = 60 * 60 * 24 * days_before_archive
# debug on or off?
DEBUG = true
#
#
##############################################

# var for calendar based backup, start with invalid value.
last_backup_day = 367


#################################
# subroutines

def get_current_fname(backup_dir, base_log_name)
     t = Time.now
     fname = backup_dir + '/' + base_log_name +
       t.strftime("%Y%m%d") + ".log"
     return fname
end

def archive_old_to_zip(backup_dir, base_log_name, t)
     moved = 0
     Dir.foreach(backup_dir) {
         | logfile |
         if(logfile =~ /^CID/)
             ftime = File.stat(logfile).mtime
             if(t > ftime + ARCHIVE_DAYS_SECS)
                 moved += 1 if move_to_archive(logfile)
             end
         end
     }
     return moved
end

def move_to_archive(fname)
     Zip::ZipFile.open($backup_zip_filename, 1) {
         | zfile |
         zfile.add(fname, fname)
     }
     File.delete(fname)
end

def log_text(bckup_dir, bse_log_name, txt)
     log_name = get_current_fname(bckup_dir, bse_log_name)
     logfile = File.new(log_name, "a")
     logfile.print(txt)
     logfile.close
end

###############################
# begin main program

# move to the dir for backup
Dir.chdir(backup_dir)

# Open the port and set up CID via modem_init_string.
port = SerialPort.new(port_name)
port.read_timeout = 0
port.puts(modem_init_string)

print  "Starting run with port ",  port_name,
   " and logging to dir ", backup_dir, "\n" if DEBUG

# Loop with pauses to look for data at the port we can record.
while(true)
     while(text = port.gets)
         print text if DEBUG
         # squeeze double \r, etc to just \n
         text.sub!(/[\r\n]+/, "\n")
         # log text unless it is just spaces
         if(text =~ /\S/)
             log_text(backup_dir, base_log_name, text)
             # archive old logs daily
             t = Time.now
             yday = t.yday
             if(yday != last_backup_day)
                 archive_old_to_zip(backup_dir, base_log_name, t)
                 last_backup_day = yday
             end
         end
     end
     if(DEBUG)
         msg = Time.now.to_s +
           ": dropped out of system call, restarting loop.\n"
         print msg
         log_text(backup_dir, base_log_name, msg)
     end
end

return 0

========================================