|Think about Loose Coupling|
Programmatically Updating Code with PPIby Tanktalus (Canon)
|on Jan 04, 2010 at 21:55 UTC||Need Help??|
Tanktalus has asked for the wisdom of the Perl Monks concerning the following question:
I've been toying with Locale::Maketext for our next project at work. The biggest problem (remaining - it solves a lot of problems) I have is in populating the files that need to be sent to translation. On one hand, it's awesome that I don't need to go and update 10-30 different language files every time I want to add another string. The downside is that I still have to do that eventually, so that the translators know what to translate. So the first thing popping into my head is that every call to Locale::Maketext::maketext could be found automatically, its first parameter pulled out, and we instantly have the list of strings that need translating.
With PPI, this seems to have gone fairly smoothly. Getting the first Expression from the maketext call seems to work, and it conveniently keeps the quotes, which allows me to propagate them if there are special characters (\n, \t, etc.).
The next obvious part is to automatically insert the text into the language-specific module files. One possibility is to use a templating solution that builds each file. Unfortunately, that comes with a couple downsides:
Going down this road, I got confused as to the proper incantation. There's a mental block between me and success on this, so I was hoping that someone else has gone down this road more successfully than I and could provide the missing piece. Here is what I have (ok, not really - this is just boiled down to the salient points):
It outputs the input unchanged:
What I was hoping for is more like:
(Yes, I know the example is missing the "1;" at the bottom, but it's just an example.) Thanks,
Update: ARGH. After getting Khen1950fx's "solution", I realised that I could simply mandate something like "### NEW TEXT GOES HERE" as a marker to find and insert on. But, because I still wanted to figure this out with PPI (so that people couldn't clobber my nice insert marker), I kept hacking. And then I got it.
Apparently, insert_after doesn't take multiple elements (yet?). So I have to do one after another. After trying a few things, I got to the point where I was re-finding each last-child, and inserting after that. But that got ugly fast, and didn't seem to work in my original code. And that's when I happened upon add_element. However, in that case, I found I had to remove the element from its existing doc first (which is fine, it's just the code snippet I created dynamically anyway), reminiscent of using XML::Twig. So, I simply remove and add. I also found I had to find the list - because it was the list's children where I was adding the element. Now off to "create" %Lexicon if it doesn't exist (should be much easier now that I have this working...)...