get_string should support plurals in a manner that works for multiple languages and is backward-compatible.
This solution is based on Petr's idea. The idea is that it uses the same language string 'normally', but if you give a parameter which is a low number, it looks for an alternate version of the string that ends in _1 (or _0 or _2 or _3).
Here are some example language strings:
$string['blah'] = '$a green bottles sitting on the wall';
$string['blah_1'] = 'One green bottle sitting on the wall';
$string['blah_2'] = 'Two green bottles sitting on the wall';
Code using this:
print_object(get_string('blah','mymodule',1)); // One green bottle sitting on the wall
print_object(get_string('blah','mymodule',2)); // Two green bottles sitting on the wall
print_object(get_string('blah','mymodule',3)); // 3 green bottles sitting on the wall
Some notes about the logic here:
1. This code supports only numbers 0, 1, 2, and 3 for this special handling. In English there are cases where special handling is appropriate for 0 ('none', different wording) and 1 (singular). According to http://en.wikipedia.org/wiki/Grammatical_number#Dual_number there are some other languages which need different handling for n=2 (and some archaic ones that need different handling for n=3).
2. The search route is completely unchanged. This code only operates after it has already found the base string ('blah' in the case above). It only ever finds plurals specified in the same place.
This is necessary because plurals might be implemented in one language but not another. For example if there is a blah_1 for English, but only blah for French, the user should still see the French version in preference. This does have the consequence that it is not possible to override a plural language string without also overriding the singular version.
3. Since get_string is frequently called, I have written the code in such a way as to maximise performance. I am unable to find a measurable before/after difference in performance (variation between tests is greater than the difference). [Note that our performance tests used a PHP accelerator; we presume that heavily-loaded sites will also be in this situation.]
See attached patch for code.