Question

I have worked in companies that to achieve translations based on the user's localization they use a file to store those translations. However, when they try to access a translation on that file they commonly do it with "magic" strings like this:

Translate("$global.name")

Translate(string keyword); is a function that looks up into these files with that keyword and the current user language code.

the xml file to access that translation looks like this:

<word code="$global.name">
    <localization lang="es-MX">
        <![CDATA[nombre]]>
    </localization>
</word>

I have read that using magic strings is a bad practice since is subject to run-time errors and becomes a nightmare when you have to change a magic string in multiple locations.

How magic strings should be avoided in this situation?

Was it helpful?

Solution

Your example is not the much maligned "magic string", rather its a bit like a Translation Dictionary, where you supply the dict key (which is a string) and get back a value. Now, your code is not ideal because I could mistype string value "$globl.name" and not know until runtime that I messed up, but that's not the worst thing in the world.

Here's an example of what I would call a magic string, by which I mean that for all possible string choices, there is a non-obvious one that triggers the code to do something else:

void DoThing(string inputString) {
    if (inputString == "foobar") {
        dbConnection.DoSomethingUnusual();
    }
    dbConnection.MakeSomeWidgets(inputString);
}

In the above example, I would have to read every line of the function to know how it would behave based on different values for the input string param. Some values of the param 'magically' trigger the function to do different things, with the type system being of no help to let me know ahead of time what's going to happen.

Back to your example, as has been said by others, you could resolve your concerns about the strings by using constants or enums to lock down the Translate() callsites in some manner.

// Somewhere global
public const string Translate_Name = "$global.name";

// At callsite
Translate(Translate_Name)

OTHER TIPS

There is no such thing as a "magic string" all the definitions on the web would be better called "hard-coded values"

A magic number is a hard-coded value that has no relation to the information it is encoding.

int Port = 80 // hard-coded value, literally the value to use for the port

where UserType == 7 // magic number

You don't get magic strings because its trivial to make the string explanatory

where UserType == "admin" // literally the type of user

You would have to be a super genius HaX0r to code something like

where UserType == "seven" //mind blown!

In your translation example the strings and their values are not hard coded but held in a configuration file. Only the key value is hard coded in the code which retrieves the value.

Obviously hard-coded values are also a bad thing and it would be great to have compile time checking of the existence of the key, say for example by using static classes, but often the jobs of writing the code and doing or updating the translations are separated. So in practice this is not preferred.

Licensed under: CC-BY-SA with attribution
scroll top