Ara.T.Howard wrote:
...
>   class JobRunner
>     class AbstractJobRunner
...
>     end
>     class FTPJobRunner < AbstractJobRunner
...
>     end
>     class HTTPJobRunner < AbstractJobRunner
...
>     end
>     class SCPJobRunner < AbstractJobRunner
...
>     end
>     class << self
>       def new job
>         klass =
>           case job.input
>             when %r|^ftp://|
>               FTPJobRunner
>             when %r|^scp://|
>               SCPJobRunner
>             when %r|^http://|
>               HTTPJobRunner
>           end
>         klass::new job
>       end
>     end
>   end

In this kind of situation, I like to try to refactor so that the
switching is done in the subclasses rather than a big case (as I'm sure
you would have done if this had been a real example with a large number
of cases). That can be done, for example, by:

  require 'subclass-keeper' # see below

  class JobRunner
    class AbstractJobRunner
      extend SubclassKeeper
      def initialize(*args); end
    end
    class FTPJobRunner < AbstractJobRunner
      PAT = %r|^ftp://|
    end
    class HTTPJobRunner < AbstractJobRunner
      PAT = %r|^http://|
    end
    class SCPJobRunner < AbstractJobRunner
      PAT = %r|^scp://|
    end
    class << self
      def new job
        klass = AbstractJobRunner.proper_subclasses.find do |c|
          c::PAT === job.input
        end
        klass::new job
      end
    end
  end

  job = Object.new
  def job.input; "scp://foo.bar"; end

  jr = JobRunner.new job
  p jr.class   # ==> JobRunner::SCPJobRunner

----- subclass-keeper.rb ----

# Extend a class by SubclassKeeper to record all subclasses (including
itself)
# and make the list available with the #subclasses method.
module SubclassKeeper
  def inherited(sub)
    super
    add_subclass(sub)
  end
  def add_subclass(sub)
    superclass.add_subclass(sub) if superclass.respond_to? :add_subclass
    (@proper_subclasses ||= []) << sub
  end
  protected :add_subclass
  def proper_subclasses
    (@proper_subclasses ||= []).dup
  end
  def subclasses
    proper_subclasses.unshift(self)
  end
end

if __FILE__ == $0
  class Base
    extend SubclassKeeper
  end

  class Sub1 < Base; end
  class Sub2 < Sub1; end

  p Base.subclasses
  p Sub1.subclasses
  p Sub2.subclasses
end