From: Robert Klemme Date: 2008-06-19T22:22:15+09:00 Subject: Re: Advice for pluggable architecture 2008/6/19 Robert Dober : > Dear list > > I am currently working on a new project (actually it is very old in my > head >3 years) which I called Rubyfilter. Hey, this sounds like fun! > I know exactly what I want it to do, not bad ;). But before I ask the > question it might be useful to describe its context. > > Rubyfilter will be more or less what the name says, a classic filter > program -as defined in the good ol'Unix way- taking some input and > producing some output. > > The way how the output is produced by the input is almost completely > undefined and depends on what I call a mode. My intention is to > provide at least an html mode with the first version and a rich? > toolbox to implement new modes easily. > > The mode is defined in the first line of the input and then everything > else is passed into the "handler" as defined for that mode. I am not sure whether this is a good idea: you force selection of the algorithm into the data stream. This will make some tasks ugly, namely you would have to do something like this { echo "myMode; ls -lR; } | rubyfilter { echo "myMode; ls -lR; } | ruby -r rubyfilter I'd prefer making the mode part of the filter command line, i.e. ls -lR | rubyfilter myMode ls -lR | ruby -r rubyfilter myMode or even chaining with ls -lR | rubyfilter myMode,myOtherMode ls -lR | ruby -r rubyfilter myMode,myOtherMode > It shall be *extremely* easy to write new modes and I have come up > with the following model. > > > (1) There is one main file to be required called > lib/rubyfilter/runner.rb it defines a class Rubyfilter and a class > method run_file, there will be a commandline frontend bin/rubyfilter > too. What about just requiring rubyfilter and let that automatically do the work? > (2) Writing a mode means putting a file with the name .rb into > lib/rubyfilter/modes and defining an instance method > RubyfilterMode#process_data. This method will be called with two IO > objects the first being the input (containing all input but the > modeline), the second being the output. RubyfilterMode is a module > that will be used to extend Rubyfilter which I intend to use as a > singleton. I would at least provide one other filter type that is line based because this will be a typical scenario. You could do that by supplying a base class RubyLineFilter which implements #process_data as a loop and calls another method (say #process_line). > (3) lib/rubyfilter/tools contains the toolbox and groups methods > depending on their use into different modules. It is up to the toolbox > user to include these modules into the RubyfilterMode module and thus > into the singleton Rubyfilter or create her own objects with the > behavior of these modules. I am not sure I have completely understood what you need the singleton for. Personally I would reverse the registration logic, i.e. not everybody needs including their filter in a module but rather record every time a module / class is inherited: An alternative approach to registration: have a base module / base class which listens to #inherited and records all instances that are subclassing it. Make the filter provide a identification method (could be the class name by default) and update a Hash with the name to class mapping. > These design decisions come from thinking, but thinking cannot replace > doing and I do not have a big experience in code organization. But > this decision surely is crucial for the acceptance of the toolkit by > potential mode implementors and shall not be object to change. I would > therefore love to have some input on this from you folks. Hopefully I could provide some input despite my limited time. Kind regards robert -- use.inject do |as, often| as.you_can - without end