GNU/Linux >> Linux の 問題 >  >> Linux

仮定を主張する - .NET Core と WSL に関する微妙なロケールの問題 Ubuntu

これは興味深い微妙なバグだと思いました 追跡するのが難しいだけでなく、突き止めるのも難しい行動でした。 「誰のせいなのか」よくわかりませんでした。

これが話です。気軽にフォローして、何が得られるか見てみましょう。

私は WSL の下で Ubuntu 18.04 を実行していました。

.NET Core 3.0 を使用してコンソール アプリを作成しました。ここで .NET Core をインストールできます http://dot.net/get-core3

私はこれをしました:

dotnet new console
dotnet add package Humanizer --version 2.6.2

次に、Program.cs を次のようにします。 Humanizer は優れた .NET Standard ライブラリです。このライブラリについて学び、「なぜ .NET にはこれがなかったのか!?」と考えるでしょう。

using System;
using Humanizer;

namespace dotnetlocaletest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(3501.ToWords());
}
}
}

アプリに 3051 という数字を単語として出力させたいことがわかります。英語が私の第一言語なので、おそらく英語ですが、ここではそれを示していないことにお気付きでしょう。実行しましょう。

このアプリは、Windows で期待どおりにうまく機能することに注意してください。

scott@IRONHEART:~/dotnetlocaletest$ dotnet run
3501

は。試しさえしませんでした。それは奇妙だ。

私の Windows マシンは en-us (米国では英語) ですが、私の Ubuntu マシンは何ですか?

scott@IRONHEART:~/dotnetlocaletest$ locale
LANG=C.UTF-8
LANGUAGE=

何でもないようです。それは「C.UTF-8」であり、何もありません。このコンテキストでの C は、POSIX のデフォルトのロケートを意味します。最も基本的なものです。 C.UTF-8 は明らかに en_US.utf8 と同じではありません。ある種の場所ですが、場所ではありません。

.NET に自分の居場所を明示的に伝えるとどうなりますか?

static void Main(string[] args)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
Console.WriteLine(3501.ToWords());
}

そしてそれを実行します。

scott@IRONHEART:~/dotnetlocaletest$ dotnet run
three thousand five hundred and one

わかりました。アプリが「Hey I'm en-US!」と宣言すれば、問題なく動作します。 Humanizer はうまく機能します。

どうしたの? Ubuntu の「C.UTF-8」は、Humanizer を英語のデフォルトに戻すほど「不変」ではないようですか?

en-US.UTF8 のようなより具体的なロケールではなく、C.UTF-8 を使用している Ubuntu のインストールで、異常または微妙な問題を他の人が見ているようです。

これはいくつかの方法で修正できます。 Ubuntu で具体的にロケールを設定できます:

locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8

幸い、Humanizer 2.7.2 以降ではこの問題が修正され、正しくフォールバックされます。それは誰の「バグ」でしたか?難しい問題ですが、この場合、Humanizer には欠陥のあるフォールバック ロジックがありました。 2.7.2 に更新したところ、C.UTF-8 はニュートラルな英語に戻りました。

そうは言っても、インストール時にWSL/Canonical/Ubuntuがローカル言語を検出し、ロケールを設定する必要があると主張できると思います。

ここでの教訓は、アプリケーション (特に、複数の言語の複数のロケールで動作することが期待されるアプリケーション) は、さまざまな場所から「入力」を受け取るということです。言い換えれば、すべての入力がユーザーから来るわけではありません。

システムのロケールと言語、時刻、タイムゾーン、日付はすべて、アンビエント コンテキストとしてアプリケーションに入力されます。 「デフォルト」とは何かについての仮定を主張してください。この場合、私の小さなアプリは en-US では問題なく動作しましたが、「C.UTF-8」ではうまく動作しませんでした。私は動作を調査し、ローカルの回避策 (必要に応じてデフォルトのロケールを検出して設定することができた) とライブラリの修正が利用可能であることの両方があることを知ることができました.

あなたの仮定を主張してください!

スポンサー: ソフトウェアのバグがわかりにくくて困っていませんか? Raygun.com のエラー監視により、顧客が期待する価値のあるエクスペリエンスを顧客に提供します。数分でインストールできます。今すぐお試しください!


Linux
  1. Ubuntu ラップトップの外観をテーマでカスタマイズする

  2. GDB とコアダンプのトラブル

  3. 自己完結型の ASP.NET Core アプリケーションを Ubuntu で実行する

  1. systemdでコンピューターの時刻と日付を制御する

  2. Ubuntu16.04でlibmodsecurityとOWASPModSecurityコアルールが設定されたNginx

  3. .Net Core で Linux デーモンを作成する方法

  1. Lokiとfzfでシェルの履歴をレベルアップ

  2. スクリプトとscriptreplayを使用して端末を記録します

  3. Ubuntu 22.04 に NVM と Nginx を使用して Node.js をインストールする方法