Windows Azure SDK for .NET June 2012 日本語パック

こちらなんですが、Web Platform Installer (通称:WebPI) からインストールすると英語になります。
日本語パックはコチラ:Download Center – Windows Azure SDK for .NET – 2012 年 6 月になります。つまりは、マニュアルでインストールする場合ということです。
何かの間違いで日本語以外の言語で表示された場合にはLanguageを日本語にすると、言語パックが表示されます。
Visual Studio のバージョンによって使用すべきファイルが違いますのでご注意を。
VS 2010 なら、VS100と書かれているものを。 VS 2012 RC なら、 VS110 と書かれているものを使用してください。

ベトナム語の文字コード-VISCII

ベトナム語はいったいどんな文字コードなんだろう?と調べてみました。
今日でこそ Unicode にベトナム語の装飾ゴテゴテの文字が収録されていたり、結合文字で解決できる訳ですが、それ以前はどうしていたのかと-つまり、日本で言うところの Shift-JIS とか JIS X 0201 とかに対応するモノは…という話で。

探してみると”VISCII”, “TCVN “というモノがあるそうです。

この”VISCII”、コード表を見てみると、もはや反則技とも思えるような荒技が繰り広げられておりました。

制御領域にも派手に文字が割り当てられております。
0×80-0x9Fは文字で埋まっています。
0×02, 0×05, 0×06, 0×14, 0×19, 0x1E にも文字が割り当てられております。

いいのかよ…
確かに、0x1F以下に定義されている文字は、ベトナム語ではほぼ出現することが無い文字(組み合わせとしてはあり得る)なので、まぁいいっちゃいいのでしょうが…

なお、各種資料をあさってみると、RFC 1456 と共にカリフォルニア州で作られたらしいので、ベトナムの国家規格という訳ではありません。

一方の”TCVN”の文字コードは、”TCVN 5712″。こちらは国家規格で、日本的には”JIS”みたいなもんでしょう。
文字コード表はこちら
まるでISO-2022 シリーズのような表です。

まぁ、実際には、Unicodeを使うのが一般的なのですが、こんなのもありますって話で。

Windows Azure SDK for .NET June 2012 の地味に嬉しい機能

と、言うわけで、昨日 Windows Azure の更新がアナウンスされたわけです。
総括的な内容とか「ここが凄い」ってのは大手どころで色々と書かれているので割愛します。

個人的に、地味に嬉しい、地味にやるなぁと思ったのはコレ。
前バージョン (Nov. 2011) と Side-by-Sideでインストールできるということ。
共存可能とは地味にやるなぁと思ったわけです。

バージョン番号は以下のようになっているので、参照設定の時はご用心と。
Nov. 2011 がバージョン 1.0 / 1.1
Jun. 2012 がバージョン 1.7

但し、Windows 8 上では Nov. 2011 はサポート外なので Jun. 2012 に上げてね と書かれています。

#まぁ、互換性を考慮しなきゃいけなくなったってことは、要するにそれだけ普及したということでもあるのでしょう。

続:ạに関する諸問題

Windows の標準ベトナム語入力からạを入力すると二文字になるというのは、前回の記事。

ですが、Wikipedia上では、一文字の「合成済み」が標準として使われているようです。(Wikipediaの規約などを調べたわけではないので推測です。)

なので、ベトナム語版Wikipedia で「ホーチミン」のページを開くと、URLは下図のようになります。(Firefox 10 の場合。)

URLをWord に貼り付けると、こうなります。

http://vi.wikipedia.org/wiki/H%E1%BB%93_Ch%C3%AD_Minh

 

さて、このURLをWindowsから手入力してみます。” Hồ_Chí_Minh”を上記URLの/wiki/ の後に貼り付けます

URLを同様にWordに貼り付けると、こうなります。

http://vi.wikipedia.org/wiki/H%C3%B4%CC%80_Chi%CC%81_Minh

 

二つのURLは厳密には違うところに注意してください。

しかしながら、Wikipediaは両者を「同じもの」とみなして、同じ内容を表示しています。

 

ここまで来るともう少し意地悪してみたくなります。

これら二つの「ホーチミン」を検索エンジンに投入するとどうなるのか?

さっそくBingとGoogleでやってみました。(Firefoxの検索ボックスから投入しただけという、実に手抜きなテストです。)

それぞれ、上段が合成文字、下段が合成済み文字です。

Bing

Google

 

なかなか見事な結果がとれました。

Bingはこれら二つを「別のもの」として扱っています。そのため、検索結果は大きく割れて、合成文字で入力した場合には欲しい情報が得られない可能性があります。

Googleはこれら二つを「同一のもの」として扱っています。結果はほぼ同じです(1億超を全部比較したわけではないので断定はしません)。

ạ に関する諸問題

日本人があまり目にすることはない字ですが、確かに世の中に存在します。
ベトナム語で使用される文字です。”a”に、声調記号の.が付加された文字です。
(豆:thanh nặnh という声調を表す記号です。)

で、この文字を、Windows から標準ベトナム語入力を使用して入力すると、
U+0061 (Latin Small Letter A)
U+0323 (Combining Dot Below)
の二文字になります。二文字ですが、aの真下にドットが描画されるのが正しい動きです。考慮されていないフォントの場合には、aの次に文字化け記号が表示されることがあります。

ところが、同じ文字を iOS から入力してみたところ、
U+1EA1 (Latin Small Letter A With Dot Below)
という文字になりました。

前回の記事 続:「が」と「が」は等しいか? の問題が「何から入力したか」によっても発生するわけです。

どちらが正しいとかそういう話ではなく、混乱の元になりそうな話ではあります。
何も考えずに単に「文字」として比較すると酷い目にあえそうな、そんな感じです。

続:「が」と「が」は等しいか?

前回は「が」の話でしたが、今度は「ệ」です。
以前「今更な文字列長の話」で取り上げた文字です。

これをWindows 7 + 標準のベトナム語入力メソッド で入力すると、合成文字になります。
ê : U+00EA に、声調記号の下ドット U+0323 (Combining Dot Below) が結合しています。

ですが、「が」の時と同じように、全く同じ文字が別のコードに割り当てられています。

「ラテン拡張追加」の U+1EC7 に “Latin Small Letter E With Circumflex and Dot Below” として が割り当てられています。たとえば Wikipedia 上では、こちらの U+1EC7 を使うのが一般的なようです。

そこで簡単な実験。Wikipedia で「ベトナム」のページを開きます。画面右にベトナム語での国号が書かれています。ブラウザ内検索 [Ctrl] + [F] で「ê」を検索します。
結果は、「ヒットしない」です。(IE9 と Firefox 9.0.1 で検証)
(まぁこのページで実験していただいてもよいのですが…)

確かに文字コードとしては別物ですが、ユーザーはそうは考えないかもしれません。
例えば、なぜ画面上に表示されている「か」を検索できないのかを義母に説明するとか、そういうことを考えるとちょっと恐ろしくなります。

「が」と「が」は等しいか?

間違い探しクイズのような感じですが、この二つの「が」は厳密には違います。

「が」 – U+304C

「が」 – U+304B U+3099

と、異なる文字で記述しています。見た目は(フォントなどによりますが)一緒です。話がややこしくなるので、1文字の方を「」、2文字の方をが」とします。
(U+3099 は、”Combining Katakana-Hiragana Voiced Sound Mark” という名前がついています。結合文字用の濁点です。)

なお、手元の環境 (Win7 + ATOK) で「が」を入力すると1文字の方の」でした。

ということは、String.Length をとると…

」 = 1

が」 = 2

となります。さらに、これらを入れたStringを比較すると…

Dim strOne As String = "が"  '---一文字の方です

Dim strTwo As String = "が"  '---二文字の方です

MsgBox(strOne = strTwo) '---FALSE が表示される

となります。確かにString オブジェクトの中身という観点では正しい挙動なのですが、見た目が同じなのでかなりややこしい問題の元になりそうです。

これをこうしてみます。

Thread.CurrentThread.CurrentCulture = New Globalization.CultureInfo("ja-JP")

MsgBox(String.Equals(strOne, strTwo)) '---FALSEが返却されます

MsgBox(String.Equals(strOne, strTwo, StringComparison.CurrentCulture)) '---TRUEが返却されます

後者のコードは、明示的に”ja-JP”カルチャーで比較するようにしたものです。

このあたりについては、MSDN : .NET Framework で文字列を使用するためのベスト プラクティス に詳しいのですが、やたらと話が入り組んでいてわかりにくいのが難点です。

書評:Cooking for Geeks

Cooking for Geeks – 料理の科学と実践レシピ

発行:オライリー・ジャパン

書店のオライリーの棚に料理本という「?」な状況に思わず買ってしまいました。まぁ、趣味としての料理も嫌いではないので。

さて、”for Geeks”と銘打っているだけあって、書き方はいろいろとそそります。食材の「入力」、時間と温度の「変数」など。
タンパク質の温度による変性、フライパンの材質による熱伝導と反応速度、材料加熱・解凍における熱勾配など、科学的に解説されていて、実に興味をそそりますし、勉強になります。

しかしながら、良くも悪くも米国の書籍の翻訳です。本文中に出てくる各単位系がヤード・ポンド系なのは実に残念です-例えばグラフの軸は華氏ではなく摂氏にすべきではなかったのでしょうか。
同様に、どうやっても米国風の肉中心・デザートが中心で、魚はあまり登場しません。さらに、米国食品医薬品局の基準やニューヨーク州の食品衛生基準など、別にどうでもよろしいという気もします。日本の家庭には普通存在しない(設置も難しい)機材の使い方を懇切丁寧に説かれても如何かと思います。(液体窒素なぞ常人には手に入りません-が、そこはネタの章なので。)

まとめ:
立ち読みで十分です。その上で、料理の化学に興味があるのでしたらどうぞ。

今更な文字列長の話

相当に今更感があるのですが、文字列長の話です。
普通に考えれば、string.Lenth か、Len(String) 取ればいいんじゃね?と思うのですが、残念ながら…というお話です。

よーくMSDNを読んでみて下さい。
まずは、String.Length の解説
「プロパティ値」に「現在の文字列の文字数。」と書いてありますが、その下の「解説」の冒頭に、「Length プロパティは、このインスタンス内の Char オブジェクトの数を返します。Unicode 文字の数ではありません。」と書いてあります。

Char の数 ≠ 文字の数

ということです。これがどういうコトかは、後ほど改めて説明します。

お次は Len です。
こちらも「文字列内の文字数または変数を格納するために必要な公称バイト数を表す整数を返します。」と書かれています。この「または」以下がくせ者です-まるで法律の但し書き条項のようにくせ者です。
解説欄をよく読むと、まるでVB6以前のファイルの扱い方の解説を読んでいるような気分になります-FilePutなんて何時の話だと…。

どちらも何故こんな回りくどい言い回しをしているのか?何故素直に「文字列長」と言えないのか。
そもそも、VB.NETに移行することによって、 Len と LenB の混乱から逃れたのではなかったのか。

残念ながら、そうではないのです。
理由は大きく分けて二つあります。
一つは「サロゲートペア(代用対)」問題。Unicodeの16bitから溢れて、32bit(=Char 二つ分)で一文字を表す文字が存在することです。更に悪いことに、日本語にはそれにが居るということです。
もう一つは、他の言語で使われる「合成文字」です。こちらもコードとしては2byte以上(合成するだけ)必要ですが、表現する文字としては「1文字」です。濁点・半濁点を考えてもらえれば良いでしょう(実際、一部の体系ではそうですし)。

これらの問題を解決した上で「文字列」の長さをきちんと数えるには、System.Globalization.StringInfo を使用しなければいけないのです。

論より証拠。実際にやってみましょう。


こんなモノを用意してみます。一番上のテキストボックスに入れたTextの文字数を表示するというモノです。

コードはこんな感じです。ここでは実験が目的なので、何も考えずにコードビハインドに書きます。

    Private Sub cmdExec_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles cmdExec.Click
        Dim strTarget = Me.txtTest.Text
        '一つめのテキストボックスには、単純にString.Length
        Me.txtLength.Text = strTarget.Length.ToString()
        '二つ目はLEN
        Me.txtLength2.Text = Len(strTarget).ToString()
        '三つめは国際化対応
        Dim g As New System.Globalization.StringInfo(strTarget)
        Me.txtLength3.Text = g.LengthInTextElements.ToString
    End Sub

では、実行結果。

まずはとりあえず「あ」でテストしてみます。

どれも一文字と表示しています。

次はサロゲートペア(代用対)の問題です。
よく知られているのは「𠮟る」ですが、その辺りの一覧はコチラにあります。

見事に割れました。見ての通り、「文字数」としての正解は「1文字」なので、正しく値を返しているのは、System.Globalization.StringInfo のみということになります。

このサロゲートペア(代用対)は、確かに高頻度に現れる問題ではないとはいえ、ハマるとデカいという落とし穴になっています。コードを書く側もテストする側も、「お約束のヒトネタ」として押さえておくと良いでしょう。

#おまけ:[アクセサリ]→[システムツール]→[文字コード表]でも、Unicodeの直接入力が4文字まで(!)です。𠮟(U+20B9F)はどうするんだと…
#もう一つ。wordpress を使用しているのですが、素のママで𠮟(U+20B9F)を投入したら、そこで投稿が打ち切られました(内部でなんか落ちたのかなと…)。これで小一時間悩みました…。こうなりますと言うことで。

最後に、外国語の合成文字の問題です。
日本語の濁点・半濁点付きの文字も「一文字」として割り振られています。例えば、「が」は U+304C です。が、そうではない言語もあります。ここではベトナム語を取り上げます。(現代の)ベトナム語は、アルファベットと声調記号の合成で表現されます。例えば「ベトナム」のことは”Việt Nam”と書きますが、これの”ệ”は、実は合成文字で二文字です。が、実際上は1文字として認識されます。(「が」を二文字と数える日本人がどれだけ居ますか?というのと同じです。)

こちらもズレました
バイト数で切ると、文や語の途中で打ち切られる可能性があります。

と言う訳で、文字列長とバイト長は使い分けましょうというお話でした。

VB.NET で Razor記法を試す

ASP.NET MVC3 といえば Razor が重要なポイントですが、それをVB.NETでやろうとするとどうなるのか。

基本的には@の使い方なので、C#とさしたる違いはなさそうに見えます。が、そうも行かない微妙な差異があります。
C# だと .cshtml だったのが .vbhtml になるというファイルの拡張子の話もありますが、まぁそれは置いておきます。

まず、いきなり一行目から違います。

@ModelType ...[モデル名]

同じコードをC#で書くと…

@model ...[モデル名]

となります。Visual Studio からViewの追加を行った場合には自動的に追加してくれるのですが、サンプルをコピって…という場合には一瞬困ります。

次はこちらです。

@Code
    ViewData("Title") = "ホーム ページ"
End Code

これをC#にすると

@{
    ViewData["Title"] = "ホーム ページ"
}

となります。この”Code” “End Code” がなんともかんとも…という感じです。

この冒頭部を乗り越えてしまえば、.vbhtml内はC#とほとんど…と言いたいところですがそうは行きません。
たとえば、ループ処理内で詳細ページへのリンクと国名・国コードを出すようなコードはこんな感じになります。
(AdventureWorks の CountryRegion, CountryRegionCurrency を使って書いた例です。)

    @For Each country In Model
        @<tr>
            <td>@Html.ActionLink("詳細", "Detail",New With{.CountryRegionCode = country.CountryRegionCode}) </td>
            <td>@country.Name [@country.CountryRegionCurrencies.Count]
            <td>@country.CountryRegionCode</td>
        @</tr>
    Next   

Forループの書式もですが、匿名オブジェクトの作成方法と初期化方法にも注意が必要です。
匿名オブジェクトはMVC3では頻出です。New と With に気をつけてサンプルから持ってきても”.”を忘れがちです。

さらに、詳細ページでは…

        <td>@Html.DisplayFor(Function(x) x.CountryRegionCode)</td>
        <td>@Html.DisplayFor(Function(x) x.CurrencyCode)</td>

Html.DisplayFor など、引数にLinqの式をとる構文の場合、このような冗長な感じになってしまいます。
この例では一行で済んでいますが、複数行で”End Function”まで書く羽目になった日にはかなり涙目です。

やはり、VB.NETでのラムダ式は、もう少し簡素な方式を望みたいところであります。