how to design plugin functionality

Discussion in 'Ruby' started by Florian Weber, Jun 16, 2004.

  1. hi!

    i have a design question. for example i have a class which reads a file
    and prints out each line with line numbers. what if now i wanna be able
    to plugin some functionality which sorts the file, depending on some
    conditions (extension, etc) before its passed on to the line numbering
    functionality. the class should be as less tied as possible to the
    sorting
    functionality as possible..

    how would you normally design that in ruby?

    would you just overwrite the method which calls the file read method
    and passes it to the numbering method?

    would you pack an object in between, which would check if the file
    has to be sorted, because the conditions are true, read the file and
    the return the sorted or unsorted content?

    basically im wondering if its considered a good practice to overwrite
    methods on the same class or if its kinda hackish.. =)

    thanks a lot!

    ciao!
    florian
     
    Florian Weber, Jun 16, 2004
    #1
    1. Advertising

  2. Florian Weber

    Zach Dennis Guest

    I would maybe add a filter class (TextFilter maybe?) and then add them as an
    aggregate objects to your File reading class, I'd maybe have 2 types of
    filters.

    - Inprocess filter (while you're reading in the files by lines)
    - Postprocess filter (after you've read the file in)

    So maybe a outline like:

    class TextFilter
    def read( text )
    return text
    end
    end

    class SortTextFilter < TextFilter
    def read( text )
    text = self.sort( text )
    end

    def sort( text )
    #Sort text, maybe ascending by default
    return text
    end
    end

    fr = FileReader.new( SortTextFilter.new() );
    fr.read( "myfile.txt" )
    puts fr

    Whatcha think?

    Zach








    -----Original Message-----
    From: Florian Weber [mailto:]
    Sent: Wednesday, June 16, 2004 11:11 AM
    To: ruby-talk ML
    Subject: how to design plugin functionality


    hi!

    i have a design question. for example i have a class which reads a file
    and prints out each line with line numbers. what if now i wanna be able
    to plugin some functionality which sorts the file, depending on some
    conditions (extension, etc) before its passed on to the line numbering
    functionality. the class should be as less tied as possible to the
    sorting
    functionality as possible..

    how would you normally design that in ruby?

    would you just overwrite the method which calls the file read method
    and passes it to the numbering method?

    would you pack an object in between, which would check if the file
    has to be sorted, because the conditions are true, read the file and
    the return the sorted or unsorted content?

    basically im wondering if its considered a good practice to overwrite
    methods on the same class or if its kinda hackish.. =)

    thanks a lot!

    ciao!
    florian




    ---
    Incoming mail is certified Virus Free.
    Checked by AVG anti-virus system (http://www.grisoft.com).
    Version: 6.0.705 / Virus Database: 461 - Release Date: 6/12/2004

    ---
    Outgoing mail is certified Virus Free.
    Checked by AVG anti-virus system (http://www.grisoft.com).
    Version: 6.0.705 / Virus Database: 461 - Release Date: 6/12/2004
     
    Zach Dennis, Jun 16, 2004
    #2
    1. Advertising

  3. Florian Weber

    Ara.T.Howard Guest

    On Thu, 17 Jun 2004, Florian Weber wrote:

    > hi!
    >
    > i have a design question. for example i have a class which reads a file
    > and prints out each line with line numbers. what if now i wanna be able
    > to plugin some functionality which sorts the file, depending on some
    > conditions (extension, etc) before its passed on to the line numbering
    > functionality. the class should be as less tied as possible to the
    > sorting
    > functionality as possible..
    >
    > how would you normally design that in ruby?
    >
    > would you just overwrite the method which calls the file read method
    > and passes it to the numbering method?
    >
    > would you pack an object in between, which would check if the file
    > has to be sorted, because the conditions are true, read the file and
    > the return the sorted or unsorted content?
    >
    > basically im wondering if its considered a good practice to overwrite
    > methods on the same class or if its kinda hackish.. =)
    >
    > thanks a lot!
    >
    > ciao!
    > florian


    first i'd separate the notion of a file's lines into it's own class - one that
    simply loads a file and provides a method to access those lines, but does no
    printing. then i'd design outputter classes that operate on line sets.
    somewhere in between you can filter/munge the lines - possible using a class
    hierarchy of Mungers, possibly using duck-typed objects which respond_to?
    'munge', possibly just using callbacks (Procs). this uses the last approach:

    ~ > cat a.rb
    class LineSet < Array
    attr :path
    def initialize path
    super()
    @path = path
    replace(IO.readlines(path))
    end
    def munge(*procs)
    c = self.cp
    unless procs.empty?
    procs.each{|pc| c = pc.call(c)}
    else
    c = yield c
    end
    c
    end
    def munge!(*procs, &block)
    replace(munge(*procs, &block))
    end
    def cp
    Marshal.load(Marshal.dump(self))
    end
    end
    class Outputter
    def initialize lines
    @lines = lines
    end
    def output out
    raise NotImplementedError
    end
    end
    class NumberedOutputter < Outputter
    def output out = STDOUT
    @lines.each_with_index do |line, idx|
    out << "#{ idx }: #{ line }"
    end
    end
    end


    lines = LineSet.new __FILE__

    reverser = lambda{|ls| ls.reverse}
    shrinker = lambda{|ls| ls[0,2]}

    puts '----'
    munged = lines.munge reverser, shrinker
    no = NumberedOutputter.new munged
    no.output

    puts '----'
    lines.munge! shrinker, reverser
    no = NumberedOutputter.new lines
    no.output

    ~ > ruby a.rb
    ----
    0: no.output
    1: no = NumberedOutputter.new lines
    ----
    0: attr :path
    1: class LineSet < Array



    -a
    --
    ===============================================================================
    | EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
    | PHONE :: 303.497.6469
    | A flower falls, even though we love it; and a weed grows, even though we do
    | not love it. --Dogen
    ===============================================================================
     
    Ara.T.Howard, Jun 16, 2004
    #3
  4. il Thu, 17 Jun 2004 00:10:40 +0900, Florian Weber
    <> ha scritto::

    >hi!
    >
    >i have a design question. for example i have a class which reads a file
    >and prints out each line with line numbers. what if now i wanna be able
    >to plugin some functionality which sorts the file, depending on some
    >conditions (extension, etc) before its passed on to the line numbering
    >functionality. the class should be as less tied as possible to the
    >sorting
    >functionality as possible..
    >
    >how would you normally design that in ruby?


    I'd say that you could use some kind of pattern and so on.
    You may find this thread useful:
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/48648

    As of now I'd probably use some trick similar to this:
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/97440

    to allow the user to write something like add_filter:)read) do.. end
     
    gabriele renzi, Jun 16, 2004
    #4
  5. You could use modules:

    module SortedOutput
    def read
    @lines = File.readlines(@file).sort
    end
    end

    Then you can do:

    class MyFileOutputter
    def initialize(file)
    @file = file
    end

    def read
    @lines = File.readlines(@file)
    end

    def output(io=$stdout)
    read unless @lines
    @lines.each_with_index do |line, i|
    io.puts "#{i+1}. #{line}"
    end
    end
    end


    outputter = MyFileOutputter.new("myfile.txt")
    outputter.extend SortedOutput
    outputter.output

    I find mixing in Modules that replace methods on object instances pretty
    handy.

    -rich


    On 6/16/04 11:10 AM, "Florian Weber" <> wrote:

    > hi!
    >
    > i have a design question. for example i have a class which reads a file
    > and prints out each line with line numbers. what if now i wanna be able
    > to plugin some functionality which sorts the file, depending on some
    > conditions (extension, etc) before its passed on to the line numbering
    > functionality. the class should be as less tied as possible to the
    > sorting
    > functionality as possible..
    >
    > how would you normally design that in ruby?
    >
    > would you just overwrite the method which calls the file read method
    > and passes it to the numbering method?
    >
    > would you pack an object in between, which would check if the file
    > has to be sorted, because the conditions are true, read the file and
    > the return the sorted or unsorted content?
    >
    > basically im wondering if its considered a good practice to overwrite
    > methods on the same class or if its kinda hackish.. =)
    >
    > thanks a lot!
    >
    > ciao!
    > florian
    >
    >
    >
    >
     
    Richard Kilmer, Jun 16, 2004
    #5
  6. im really sorry. i think it was really misleading to give such a
    concret example. basically the example i gave is purely fictional.

    basically i was more wondering if overwriting methods (methods of
    the same class, not methods of a superclass) is a recommended
    good practice for functionality which can be plugged in or
    if such things should be done in a traditional way, where a object
    is 'plugged' in between, which decides if the additional functionality
    should be executed or not.

    sorry for the misunderstanding =)

    ciao!
    florian
     
    Florian Weber, Jun 16, 2004
    #6
  7. Florian Weber

    Zach Dennis Guest

    I think overriding the methods of the existing class is poor choice. The
    only reason that I would suggest this is if there was some drastic
    performance issue when moving the functionality outside of the class, but I
    don't see that happening. It is better program design to leave the original
    class alone. It makes your code more readable, reusable and maintainable. It
    also allows your class to be more reusable for other projects and other
    people.

    I suggest a book reading...

    "Design Patterns
    Elements of Reusable Object-Oriented Software" by Erich Gamma, Richard
    Helm, Ralph Johnson and John Vlissides.

    It's a deep reading, but it's a good one.

    HTH,

    Zac





    -----Original Message-----
    From: Florian Weber [mailto:]
    Sent: Wednesday, June 16, 2004 4:42 PM
    To: ruby-talk ML
    Subject: Re: how to design plugin functionality


    im really sorry. i think it was really misleading to give such a
    concret example. basically the example i gave is purely fictional.

    basically i was more wondering if overwriting methods (methods of
    the same class, not methods of a superclass) is a recommended
    good practice for functionality which can be plugged in or
    if such things should be done in a traditional way, where a object
    is 'plugged' in between, which decides if the additional functionality
    should be executed or not.

    sorry for the misunderstanding =)

    ciao!
    florian



    ---
    Incoming mail is certified Virus Free.
    Checked by AVG anti-virus system (http://www.grisoft.com).
    Version: 6.0.705 / Virus Database: 461 - Release Date: 6/12/2004

    ---
    Outgoing mail is certified Virus Free.
    Checked by AVG anti-virus system (http://www.grisoft.com).
    Version: 6.0.705 / Virus Database: 461 - Release Date: 6/12/2004
     
    Zach Dennis, Jun 16, 2004
    #7
  8. On 6/16/04 4:41 PM, "Florian Weber" <> wrote:

    > im really sorry. i think it was really misleading to give such a
    > concret example. basically the example i gave is purely fictional.
    >
    > basically i was more wondering if overwriting methods (methods of
    > the same class, not methods of a superclass) is a recommended
    > good practice for functionality which can be plugged in or
    > if such things should be done in a traditional way, where a object
    > is 'plugged' in between, which decides if the additional functionality
    > should be executed or not.


    Well, methods can be replaced on classes at runtime as then can on instances
    of classes. Although changing class methods changes the behavior of all
    instances (and _could_ be very bad), changing methods on objects can be very
    powerful. I don't see any reason not to do it if the design requires that
    kind of changeable behavior. But again, all these choices need to be
    balanced against the requirements of what you are trying to do.

    >
    > sorry for the misunderstanding =)


    No problem!

    -rich

    >
    > ciao!
    > florian
    >
    >
    >
     
    Richard Kilmer, Jun 17, 2004
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. PilotYid
    Replies:
    1
    Views:
    660
    Andrew Thompson
    Oct 31, 2005
  2. Digital Puer
    Replies:
    1
    Views:
    322
    tom fredriksen
    Mar 13, 2006
  3. Marcin Cenkier
    Replies:
    1
    Views:
    5,484
    Marcin Cenkier
    Apr 12, 2006
  4. Jimmy
    Replies:
    0
    Views:
    532
    Jimmy
    Mar 15, 2007
  5. Replies:
    1
    Views:
    750
Loading...

Share This Page