Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 188679
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T16:06:32+00:00 2026-05-11T16:06:32+00:00

Ok, suppose I have Ruby program to read version control log files and do

  • 0

Ok, suppose I have Ruby program to read version control log files and do something with the data. (I don’t, but the situation is analogous, and I have fun with these analogies). Let’s suppose right now I want to support Bazaar and Git. Let’s suppose the program will be executed with some kind of argument indicating which version control software is being used.

Given this, I want to make a LogFileReaderFactory which given the name of a version control program will return an appropriate log file reader (subclassed from a generic) to read the log file and spit out a canonical internal representation. So, of course, I can make BazaarLogFileReader and GitLogFileReader and hard-code them into the program, but I want it to be set up in such a way that adding support for a new version control program is as simple as plopping a new class file in the directory with the Bazaar and Git readers.

So, right now you can call “do-something-with-the-log –software git” and “do-something-with-the-log –software bazaar” because there are log readers for those. What I want is for it to be possible to simply add a SVNLogFileReader class and file to the same directory and automatically be able to call “do-something-with-the-log –software svn” without ANY changes to the rest of the program. (The files can of course be named with a specific pattern and globbed in the require call.)

I know this can be done in Ruby… I just don’t how I should do it… or if I should do it at all.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T16:06:33+00:00Added an answer on May 11, 2026 at 4:06 pm

    You don’t need a LogFileReaderFactory; just teach your LogFileReader class how to instantiate its subclasses:

    class LogFileReader
      def self.create type
        case type 
        when :git
          GitLogFileReader.new
        when :bzr
          BzrLogFileReader.new
        else
          raise "Bad log file type: #{type}"
        end
      end
    end
    
    class GitLogFileReader < LogFileReader
      def display
        puts "I'm a git log file reader!"
      end
    end
    
    class BzrLogFileReader < LogFileReader
      def display
        puts "A bzr log file reader..."
      end
    end
    

    As you can see, the superclass can act as its own factory. Now, how about automatic registration? Well, why don’t we just keep a hash of our registered subclasses, and register each one when we define them:

    class LogFileReader
      @@subclasses = { }
      def self.create type
        c = @@subclasses[type]
        if c
          c.new
        else
          raise "Bad log file type: #{type}"
        end
      end
      def self.register_reader name
        @@subclasses[name] = self
      end
    end
    
    class GitLogFileReader < LogFileReader
      def display
        puts "I'm a git log file reader!"
      end
      register_reader :git
    end
    
    class BzrLogFileReader < LogFileReader
      def display
        puts "A bzr log file reader..."
      end
      register_reader :bzr
    end
    
    LogFileReader.create(:git).display
    LogFileReader.create(:bzr).display
    
    class SvnLogFileReader < LogFileReader
      def display
        puts "Subersion reader, at your service."
      end
      register_reader :svn
    end
    
    LogFileReader.create(:svn).display
    

    And there you have it. Just split that up into a few files, and require them appropriately.

    You should read Peter Norvig’s Design Patterns in Dynamic Languages if you’re interested in this sort of thing. He demonstrates how many design patterns are actually working around restrictions or inadequacies in your programming language; and with a sufficiently powerful and flexible language, you don’t really need a design pattern, you just implement what you want to do. He uses Dylan and Common Lisp for examples, but many of his points are relevant to Ruby as well.

    You might also want to take a look at Why’s Poignant Guide to Ruby, particularly chapters 5 and 6, though only if you can deal with surrealist technical writing.

    edit: Riffing of off Jörg’s answer now; I do like reducing repetition, and so not repeating the name of the version control system in both the class and the registration. Adding the following to my second example will allow you to write much simpler class definitions while still being pretty simple and easy to understand.

    def log_file_reader name, superclass=LogFileReader, &block
      Class.new(superclass, &block).register_reader(name)
    end
    
    log_file_reader :git do
      def display
        puts "I'm a git log file reader!"
      end
    end
    
    log_file_reader :bzr do
      def display
        puts "A bzr log file reader..."
      end
    end
    

    Of course, in production code, you may want to actually name those classes, by generating a constant definition based on the name passed in, for better error messages.

    def log_file_reader name, superclass=LogFileReader, &block
      c = Class.new(superclass, &block)
      c.register_reader(name)
      Object.const_set("#{name.to_s.capitalize}LogFileReader", c)
    end
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 109k
  • Answers 109k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Ok, thanks a lot Chris, will definitely keep this in… May 11, 2026 at 9:25 pm
  • Editorial Team
    Editorial Team added an answer In my case the following worked: KeyEvent.consume() Consumes this event… May 11, 2026 at 9:25 pm
  • Editorial Team
    Editorial Team added an answer Conversion operators can't be generic. From the spec section 10.10,… May 11, 2026 at 9:24 pm

Related Questions

Suppose I have code like this: template<class T, T initial_t> class Bar { //
I have a button that correctly wired such that when it is clicked, the
Let's take a concrete example and hope I can be clear. Suppose the (ordered)
OK, say that my application is emitting (x86) instructions into memory, making the page
I'm new to hibernate, as you'll soon see. I apologize if this question has

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.