gflohr / libintl-perl

Official repository for libintl-perl
http://www.guido-flohr.net/en/projects/#libintl-perl
GNU General Public License v3.0
5 stars 4 forks source link

N__p returns all its argument as a list which makes using the marked-up string non-transparent and troublesome #13

Open az143 opened 1 year ago

az143 commented 1 year ago

N__("some msgid") works great and its entry in the manpage explains perfectly what it does: mark a string for translation, but not translate it immediately ("for example when you also need the unmodified original string.").

if you do, however, both require the original string and translate it with/in a context, then N__p() will not work as well or out of the box: it returns all its arguments as a list, ie. the context and the msgid. this means that you cannot just write

my $onestringplease =  N__p("identifies as a verb","somemsgid");

as the list is interpreted in scalar context and your $onestringplease now contains the number 2. to retain the msgid you'd have to manually extract the second element from the result of the N__p, everywhere which defeats the purpose of a just-mark-me-up-please function like N__p.

i think that N__p should return only its msgid argument and ditch the context as that is really only relevant for the translation activity, not for the program itself at the point when N__p is called.

the situation with N__n and N__np seems even worse as the list-or-scalar aspect also applies but there doesn't seem to be a 'natural' return value for those: just the msgid, or just the plural form, or both or neither?

gflohr commented 1 year ago

That looks like missing test coverage, sorry. I'll fix it as soon as possible.

gflohr commented 1 year ago

As it turns out, that was actually by design, see https://rt.cpan.org/Ticket/Display.html?id=46471. I just forgot that issue.

The idea is that you can always feed the return value(s) of N__.*() into the corresponding __*() function and you will then get the translation, like this:

my @whatever = N__p('context', 'some message');
...
say __p(@whatever);

In a way the current implementation avoids DRY.

Do I see it correctly that you actually have a workaround for your issue by just calling the function in array context? Like this:

my (undef, $onestringplease) =  N__p("identifies as a verb","somemsgid");

If it that workaround is okay for you I would prefer to close your issue as wontfix because changing the implementation back and forth does not make sense and the use case is pretty exotic anyhow.

az143 commented 1 year ago

On Mon, 27 Nov 2023 08:19:00 -0800, Guido Flohr writes:

The idea is that you can always feed the return value(s) of N__.*() into the corresponding __*() function and you will then get the translation, like this

that makes good sense. from a round-tripping perspective it's perfect, and...

Do I see it correctly that you actually have a workaround for your issue by just calling the function in array context? Like this:

...that workaround does works but it's very unwieldy, in particular if i have to bake a bunch of translatable constants in an array or hash (where the datastructure is or needs to be translation-agnostic).

having to wrap every single one of the invocations does reduce the utility of the markup-only N__* functions quite a bit.

If it that workaround is okay for you I would prefer to close your issue as wontfix because changing the implementation back and forth does not make sense and the use case is pretty exotic anyhow.

i've got no problem with that, but a few additional pod lines with explanation/caveat about the list return situation would be great.

(related nitpickery: the N__ function prototype says one arg, whereas the manpage says/shows many).

regards az

-- Alexander Zangerl + GPG Key 2FCCF66BB963BD5F + https://snafu.priv.at/ Any suffiently advanced magic is indistinguishable from technology.