On Mon, 11 Oct 2004 09:04:40 +0900, Bill <bi11 / lynxview.com> wrote:
> 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

class BackupClass
  attr_reader :backup_dir, :base_log_name
  def initialize(backup_dir, base_log_name)
     @backup_dir = backup_dir
     @base_log_name = base_log_name
  end

> 
> 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 current_fname
    "#{backup_dir}/#{base_log_name}#{Time.now.strftime("%Y%m%d")}.log"
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

#
# I'm not entirely sure about the inject rewrite here; just 
# accumulating on moved may be just as good.
#
def archive_old_to_zip(backup_dir, base_log_name, t)
     dir = Dir.open(backup_dir)
     moved = dir.inject(0) do |lcount, ogfile|
         # Skip-logic can use trailing conditionals
         next unless logfile =~ /^CID/
         next unless t > File.stat(logfile).mtime + ARCHIVE_DAYS_SECS
         # Active logic use prefix if
         if (move_to_archive(logfile))
             next count + 1
         else
             next count
         end
     end
     dir.close
     return moved
end


# I don't like the $backup_zip_filename below; should come from 
# the object.
> 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

def log_text(txt)
     logfile = File.new(current_fname, "a")
     logfile.print(txt)
     logfile.close
end

# ... and continue refactoring into an object.  

I can do another pass if you finish the refactoring job.

Eivind.