Unexpected behaviour of changeOutputFile

2004-10-11
2013-04-25
  • Vinay Sajip
    Vinay Sajip
    2004-10-11

    Given the input

    <@pp.changeOutputFile name = "a/b/c.txt"/>
    Contents of a/b/c.txt
    <@pp.changeOutputFile name = "d/e/f.txt"/>
    Contents of d/e/f.txt
    <@pp.changeOutputFile name = "g/h/i.txt"/>
    Contents of g/h/i.txt

    I would expect three files to be created: a/b/c.txt, d/e/f.txt and g/h/i.txt, relative to where the input file is in the hierarchy.

    Instead, I get a/b/c.txt, a/b/d/e/f.txt and a/b/d/e/g/h/i.txt. This seems to be wrong behaviour - e.g. if the file names are generated in a loop, one would expect not to have the outputs appear at different levels of the output hierarchy!

     
    • Hm... I guess you didn't meant that it is a bug (as it is the documented behaviour), but that a design mistake. So, the rule is that virtual paths that do not start with "/" are relative paths, and relative output paths are resolved relatively to the directory of the *currently* written output file, as it is documented in the manual. I guess that you would prefer if they are resolved relatively to the *first* output file of the currently executed template. I say that for both logic there are cases where you would prefert the other choice... but maybe it would really more practical to use you logic. Unfortunatelly, it would be a too hard backward compatibility breaking to change this for FMPP, but I will keep it in mind this if I will do a next generation preprocessor.

      As workaround, you can <#assign base = "/" + pp.outputDirectory> at the begining of the template execution, and then use "${base}g/h/i.txt" path for the pp.changeOutputFile...

       
      • Vinay Sajip
        Vinay Sajip
        2004-10-12

        Thanks for the workaround. You could, of course, provide backwards compatibility through an additonal optional parameter whose default value has the current behaviour...

         
        • In principle, yes. I could use a strategy where it is required to specify a compatibility version number as setting (or else fmpp forks in 0.9.6 compatible mode). The problem with this is that I'm a human being, and not even a genius one, so soon it would drive me crazy to maintain the several compatibility modes to work (0.9.7 compatible, 0.9.8 compatible, etc.), also this would confuse the users (imagine, how to document such a mess?). So the strategy I follow is that I wait until a huge amount of design mistakes has accumulated, and then increment the major version number and brutally break backward compatibility. Kind of iterative evolution.