On Thursday, 26 October 2023 at 11:18:46 UTC, kdevel wrote:
> Localization
A few days ago this example was posted in the "Learn" group [1]:
writeln(i"You drink $coffees cups a day and it gives you $(coffees + iq) IQ");
A German version would read
writeln(i"Sie trinken $coffees Tassen Kaffee am Tag. Dadurch erhöht sich Ihr IQ auf $(coffees + iq).");
How could the language version be selected (at runtime)? BTW: Is there a "D way of localization"?
With gnu gettext, you'd first pass the string through a tr() function, which lets it swap out at runtime. (You'd have to remember to do this though, since writeln will accept a generic string without this step.... unless writeln itself started wrapping through a standard translator function... but that's another story.)
I wrote a sample for the interpolated version here, but the translations might not be obvious. Let me add your example as a concrete thing.
https://github.com/adamdruppe/interpolation-examples/blob/master/04-internationalization.d
It is now added there, running that program (at the time of this writing) gives:
I, Adam, have a singular apple.
I, Adam, have a singular apple.
I, Adam, have 5 apples.
I, Adam, have 5 apples.
GG Adam
GG Adam
ggs 5, Adam
ggs 5, Adam
You drink 5 cups a day and it gives you -25 IQ
Sie trinken 5 Tassen Kaffee am Tag. Dadurch erhöht sich Ihr IQ auf -25.
Note that the translator could also change word order, it uses positional params here. (I'm not entirely happy with this specific syntax but it is just a demo to show that you can do all these things.)
> Restricting Access
What about
writeln(i"You drink $coffees cups a day and it gives you $(password) IQ");
How is it prevented that the person doing the localization puts arbitrary variable or code references into the localized strings?
The localization thing is done at runtime and only has access to the variables passed to it.
If a programmer wrote "it gives you $password" then yes, password would be available to the translator, same as any other argument, but just... don't do that?
Notice how in the example linked above, the translator uses $1 and $2 rather than the variable name, since that string is handled by the library code, not the D language.
> Accessing Fields Of A Struct
would this work out-of-the-box?:
Yes, of course, exactly the same as if you passed "name", value
to the function. (That's literally what the compiler's rewrite does.)
> Accessing Elements Of An AA
writeln (i"The name in s is $(aa["name"])"
This is wrong though, it should be:
writeln (i"The name in s is $(aa["name"])"
Once you're inside the $(..) region, it is read as D code, not as part of a string. (This is pretty standard for language support of interpolation.) So you don't want extra \ in there.
I'll add these two to basics.
> That typing is laborious. Isn't there a way to bind the expression to the keys of the AA?
I don't know what this means.
> Nesting
Should it nest? How deep? What is the syntax?
It does and and deep as you want. Remember, what's inside the $() is D code, not string, so you'd do:
i"thing $(i"thing $(i"thing"))"
etc. The processing function has the info it needs to support this but may have to do extra work with it.
BTW you don't have to ask me, you can ask the compiler, this is all fully implemented already. https://github.com/dlang/dmd/pull/15715
But let me add a few of these to the examples repo.... and done
https://github.com/adamdruppe/interpolation-examples/blob/master/01-basics.d
shows all these. If you compile the dmd from the PR you can build and run all these examples yourself.