From: bbense+comp.lang.ruby.Sep.27.02@... Date: 2002-09-28T03:03:32+09:00 Subject: Re: Ruby program design question ( Pattern or AntiPattern ?) -----BEGIN PGP SIGNED MESSAGE----- In article <51172973522.20020927095543@integ.ru>, Bulat Ziganshin wrote: >Hello bbense+comp, > >Thursday, September 26, 2002, 11:36:24 PM, you wrote: > >bclrS20tse> - - I find myself repeating this kind of pattern over and over >bclrS20tse> again. I'm wondering if it's a good sign or a bad one. Here's >bclrS20tse> the pattern. > >bclrS20tse> Write a simple generic ruby class to interface to something. > >delegation pattern? please provide code example > - - Here's a trivial example. I've been using ifile to help sort spam in my ruby mailhandler. Here's the ifile class # # $Id: ifile.rb,v 1.1 2002/09/25 20:02:13 bbense Exp $ # # Ifile, a class for interacting with ifile program. # Get ifile at http://www.ai.mit.edu/~jrennie/ifile/ # # Booker C. Bense # require 'open3' module Ifile # This is the wrong name, but I can't think of anything better. class Process # Tell me where ifile lives. def initialize(path="/var/local/bin/ifile",args="--verbosity=0") if FileTest.executable?(path) then @ifile = path @args = args else raise ArgumentError end end # Given a message, query folders def query(msg) results = Array.new output = self.run_ifile(msg,"--query ") i = 0 output.each do |line| # Format of output is folder score folder , score = line.split if ( folder && score ) then tmp = Hash.new tmp['folder'] = folder tmp['score'] = score.to_f tmp['position'] = i results << tmp i = i + 1 end end return results end # Add a message to a folder def add(msg,folder) output = self.run_ifile(msg,"--insert=#{folder}") end # Delete a message from a folder def delete(msg,folder) output = self.run_ifile(msg,"--delete=#{folder}") end # Refile def refile(msg,oldfolder,newfolder) self.delete(msg,oldfolder) self.add(msg,newfolder) end # internal methods def run_ifile(msg,args) stdin, stdout, stderr = Open3.popen3("#{@ifile} #{@args} #{args}") #write msg to ifile msg.each { |line| stdin.puts line } stdin.close #Read output output = stdout.readlines stdout.close stderr.close return output end end end # module Ifile - - I used this module in several programs, sometimes I can use it without a "controller" , however I tend to end up writing stuff like this. # For dealing with ifile class IfileProcess def initialize(filterdir,default_folder) @filterdir = filterdir @default_folder = default_folder @ifile = Ifile::Process.new @same = Hash.new @same["unix-admin"] = "oldmail" @same["admin-log"] = "oldmail" @same[default_folder] = "oldmail" end # Return a full fledge path def query(msg) results = @ifile.query(msg) best = results[0]["folder"] if ( @same[best] ) then return @default_folder end dest = "#{@filterdir}/#{best}" dest.sub!(/\s/,"") return dest end def add(msg,destination) if ( @same[destination] ) then folder = @same[destination] else folder = destination.sub(@filterdir,"") folder.sub!(/[\/]/,"") # Deal with incoming/oldmail problem if ( @same[folder] ) folder = @same[folder] end end print "Adding message to :#{folder}:\n" @ifile.add(msg,folder) end end #IfileProcess - - As you can see IfileProcess has a bunch of icky knowledge about other classes and default paths that I have kept out of the simple class. Now that I think about it I could probably just as easily implement these as subclasses of the original class. It never occurs to me to do that however. - - Booker C. Bense -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBPZSbWGTWTAjn5N/lAQGXOwQAsce4r8J6weEK4CSiynA3EX5Jleq7ZCXp g4D3dJL0CHTsWCOr+XzQbP4q3XF6RE+C8qe6GRbprlQpDyRUj7vKras7HJYKeXzF 0kfl1UsdLxekK8JuRa+vvqBSeDmXt5IFHiqR6NAIdL2p5UnnsLKfz1/j4bQ0LGPt kEPHwXtySak= =lDvV -----END PGP SIGNATURE-----