Myslel jsem, že to byla zajímavá a jemná chyba chování, které bylo nejen těžké vystopovat, ale také odhalit. Nebyl jsem si jistý, „čí to byla chyba.“
Tady je příběh. Neváhejte a sledujte, co získáte.
Běžel jsem na Ubuntu 18.04 pod WSL.
Vytvořil jsem konzolovou aplikaci pomocí .NET Core 3.0. .NET Core můžete nainstalovat zde http://dot.net/get-core3
Udělal jsem toto:
dotnet new console
dotnet add package Humanizer --version 2.6.2
Potom program.cs vypadal takto. Humanizer je skvělá knihovna .NET Standard, o které se budete učit a budete si myslet „proč tohle .NET vždycky neměl??“
using System;
using Humanizer;
namespace dotnetlocaletest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(3501.ToWords());
}
}
}
Můžete vidět, že chci, aby aplikace vytiskla číslo 3051 jako slova. Pravděpodobně v angličtině, protože to je můj primární jazyk, ale všimněte si, že jsem to zde neuvedl. Pojďme to spustit.

Všimněte si, že tato aplikace funguje skvěle a podle očekávání ve Windows.
scott@IRONHEART:~/dotnetlocaletest$ dotnet run
3501
Huh. Ani se o to nepokusilo. To je divné.
Můj počítač se systémem Windows je en-us (angličtina v USA), ale jaký je můj počítač Ubuntu?
scott@IRONHEART:~/dotnetlocaletest$ locale
LANG=C.UTF-8
LANGUAGE=
Vypadá to, že o nic nejde. Je to "C.UTF-8" a nic to není. C v tomto kontextu znamená výchozí umístění POSIX. Je to nejzákladnější. C.UTF-8 rozhodně NENÍ totéž jako en_US.utf8. Je to svého druhu místo, ale není to místo.
Co když .NET výslovně řeknu, kde jsem?
static void Main(string[] args)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
Console.WriteLine(3501.ToWords());
}
A spustit to.
scott@IRONHEART:~/dotnetlocaletest$ dotnet run
three thousand five hundred and one
Dobře, takže věci fungují dobře, pokud aplikace deklaruje "ahoj, jsem en-US!" a Humanizer funguje dobře.
Co je špatně? Zdá se, že „C.UTF-8“ Ubuntu není dostatečně „invariantní“, aby způsobilo návrat Humanizeru k výchozímu nastavení v angličtině?
Zdá se, že jiní lidé zaznamenali neobvyklé nebo jemné problémy s instalacemi Ubuntu, které používají C.UTF-8 oproti specifičtějšímu národnímu prostředí, jako je en-US.UTF8.
Mohl bych to opravit několika způsoby. Mohl bych nastavit národní prostředí konkrétně v Ubuntu:
locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8
Naštěstí Humanizer 2.7.2 a vyšší tento problém vyřešil a vrací se správně. Čí to byl "bug"? Těžký, ale v tomto případě měl Humanizer nějakou chybnou logiku záložního řešení. Aktualizoval jsem na 2.7.2 a nyní se C.UTF-8 vrací zpět na neutrální angličtinu.
To znamená, že si myslím, že by se dalo tvrdit, že WSL/Canonical/Ubuntu by měl detekovat můj místní jazyk a/nebo na něj nastavit národní prostředí při instalaci.
Z toho plyne ponaučení, že vaše aplikace – zejména ty, u kterých se očekává, že budou fungovat ve více lokalitách ve více jazycích – přijímají „vstup“ z mnoha různých míst. Řečeno jinak,ne všechny vstupy pochází od uživatele.
Systémové národní prostředí a jazyk, čas, časové pásmo, data, to vše jsou vstupy jako okolní kontext vaší aplikace. Ujistěte se, že potvrzujete své předpoklady o tom, co je „výchozí“. V tomto případě moje malá aplikace fungovala skvěle na en-US, ale ne na "C.UTF-8." Podařilo se mi prozkoumat chování a zjistit, že existovalo jak místní řešení (v případě potřeby jsem mohl detekovat a nastavit výchozí národní prostředí), tak byla k dispozici také oprava knihovny.
Tvrdte své domněnky!
Sponzor: Trápí vás nejasnost ohledně softwarových chyb? Poskytněte svým zákazníkům zážitek, který si zaslouží a očekávají, pomocí sledování chyb od Raygun.com. Instalace během několika minut, vyzkoušejte to ještě dnes!