From: Robert Klemme Date: 2007-01-09T02:20:06+09:00 Subject: Re: code organisation help request On 08.01.2007 16:50, Paul van Delst wrote: > Hello, > > I've written some ruby code that creates Fortran95 code to define and > manipulate derived types (aka structures) as well as perform "regular" > (what I ambiguously refer to as "Binary") and netCDF I/O. Via a driver > script, I provide a text file with the simple structure definition to my > ruby code and out pops three modules (fortran95 modules, not ruby ones) > that I can compile. > > The way I do this currently is like so: > > f=FDefMod.new > f.read(def_file) # Parse the file containing an f95 structure > definition > f.createDefModule # Create the structure definition f95 module > f.createBinIOModule # Create the binary I/O f95 module > f.createNCIOModule # Create the netCDF I/O f95 module > > This creates three compilable f95 modules. (It's all very cool, really :o) > > The problem I'm facing is that my ruby class definition file, > fdefmod.rb, has grown unmanageably large and I want to split the code up > into more manageable pieces but I can't figure out how best to do it. > > I would like all the methods used to create the f95 definition code > (i.e. the public createDefModule and about 20 private methods) to reside > in one file, the methods to create the f95 binary I/O in another, and > similarly for the methods to create the f95 netCDF I/O code. E.g. > > fdefmod.rb : contains the FDefMod class definition and associated > methods > fdefmod_def.rb : contains the instance methods that create the f95 > structure > definition module > fdefmod_binio.rb: contains the instance methods that create the f95 > binary I/O module > fdefmod_ncio.rb : contains the instance methods that create the f95 > netCDF I/O module > > The last three files would be included (in the C sense) in the FDefMod > class definition file. All of the methods in the three "functional > categories" (def, binio, and ncio) are, of course, instance methods. > Currently, the monolithic fdefmod.rb file contains everything and it's a > nightmare to organise the code itself and associated unit tests -- to > say nothing of adding new features. > > So: how to split up the code? Module mixins? Subclasses? > > The way I see it, the above type of organisational structure, while > logical, is opposite to how one would typically use modules to mixin > methods since the methods in question aren't generic, they're very > specific. > > And inheritance doesn't seem right either since each code component I'm > trying to separate aren't really classes in their own right; they're > just a bunch of methods operating on a class to create a particular > format of output. > > In addition, there are a number of class methods that are used by all > three "functional categories" of code. These class methods are just > little utilities for formatting the output f95 code are all private to > the FDefMod class. > > I've been thinking myself in circles for a while now, so my explanation > may be malformed. If so, I apologise. > > Any ideas, suggestions, hints, etc much appreciated. I would keep FDefMod as driver (i.e. the user instantiates it and invokes a method that does *all* the work. I'd then go on to create a class containing configuration information only (this is filled from the file; an instance of OpenStruct or Hash might be sufficient depending on your config info). Then I'd go on creating three classes for the three output types if there is enough different code to justify this. You could then connect those classes in any way that seems reasonable (i.e. have a common base class that contains shared code and state, create a module and include it in all three or other). Your FDefMod.create_struct(file) will then instantiate those three classes while it goes along and those instances of your output generation classes will then create output files. If you would want to classify this with a pattern name it's a bit like nested command object pattern, i.e. you have a major command and sub commands (i.e. one per output type). Of course, this is said with the little we know about your code. There might be potential for further refactorings in the code you have (i.e. split up methods into several methods, identify common code / patterns and extract them into additional methods that are invoked in multiple places etc.). Btw, how many LOC are we talking about? Kind regards robert