Robert Klemme wrote:
> On 08.01.2007 20:28, Paul van Delst wrote:
>> Robert Klemme wrote:
>>> On 08.01.2007 16:50, Paul van Delst wrote:
>
[stuff snipped]

>> One thing I find particularly odious is that to get the above to work, 
>> I needed to make the DerivedClass methods class methods rather than 
>> instance methods.
> 
> You probably got inheritance and module inclusion mixed up.

Actually, I don't think I understand either too well. :o(

>>> 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).
>>
>> That is what I was thinking to do. Sometimes, I just need the 
>> definition module, but not the I/O ones.
> 
> I've attached a file to describe what I mean.  You can distribute that 
> code to multiple files (you'll have to open and close the module once 
> per file).

Wow. Thank you very much. I have been bumbling about trying different things the last 
couple of days but your sample code makes everything quite clear. And, it does things the 
way I was thinking about for future enhancements (mostly documentation related) - two 
proverbials with one stone. Excellent.

> If you need to do some preprocessing common to all outputs, you might 
> want to add a PreProcessor class that converts a Config into something 
> else that stores the preprocessed state (and maybe also references the 
> original config).  You can then pass that on to individual generators.
> 
>>> 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.).
>>
>> That is exactly my plan. For each of the so-called "derived classes", 
>> the same procedure can be applied again. For example, if my f95 
>> structure is named "MyStruct", then the f95 definition module that is 
>> created, MyStruct_Define.f90, would contain the public procedures,
>>   Associated_MyStruct: Check if all the pointer components are associated
>>   Create_MyStruct    : Allocate the pointer components of the structure
>>   Destroy_MyStruct   : Deallocate the pointer components
>>   Assign_MyStruct    : Deep copy the structure (a simple assignment 
>> just copies
>>                        the pointer references, not the actual data)
>>   Equal_MyStruct     : Determine if two structures are equal
>>   Info_MyStruct      : Print out info on the structure dimensions
> 
> Are you talking about Fortran or Ruby code here ^^^^?  I was talking 
> about Ruby code *only*.

Me too; although the way I constructed my post it may seem like I've conflated the two. 
The ruby code creates the Fortran code. The stuff immediately above refers to the 
Fortran95 code that the ruby code generates. Fortran95 (an 11-year old standard) contains 
pointers, allocatables, and modules. Fortran2003 contains classes, inheritance, and C 
interop (although there are no complete f2003 compilers available yet).
> 
>> The ruby methods to create each individual f95 procedure could be put 
>> into its own class with one public instance method and a bunch of 
>> private methods (for formatting particular things in the output 
>> procedure.) I could have a separate file (class?) that handles the 
>> creation of each of the above procedures in the f95 module. Same for 
>> the i/o stuff. It might make unit testing each part easier too.
>>
>> There are some methods that are used in several places to create parts 
>> of just the f95 definition module, just as there are common methods 
>> used to create parts of just the f95 I/O module; and then there are 
>> common methods used in formatting output for all three f95 modules.
> 
> Are you doing this in two steps, i.e. create Fortran modules and then 
> format and output them?  Assuming yes, this does not seem to make much 
> sense to me - you can create the Fortran code formatted right from the 
> start, can't you?

The latter is what I am doing. I use string interpolation (I think that's the right term) 
within herefiles for the dynamic bits..

>> As I added functionality, I've been refactoring a lot - that's another 
>> reason I want to split the code into smaller bits: it should allow for 
>> much easier identification of the common parts (at least, I think so.)
> 
> Yep.
> 
>>>  Btw, how many LOC are we talking about?
>>
>> Hardly any. About 3K loc. In the future I think that can be reduced 
>> quite a bit since there is still a fair amount of boilerplate 
>> Fortran95 code in there that is just getting dumped via herefiles.
> 
> Sounds good, i.e. still early enough that it's feasible and you can try 
> out variants.

Once again, thanks very much for the sample file. I'm going to be busy this weekend.... :o)

cheers,

paulv

-- 
Paul van Delst             Ride lots.
CIMSS @ NOAA/NCEP/EMC               Eddy Merckx