1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Visual BasicAdvent Calendar 2022

Day 23

【VB.NET】拡張コンパイラModVBの紹介(使い方編)

Posted at

はじめに

これは、Visual Basic Advent Calendar 2022の23日目の記事となります。

前回、ModVBのインストールの記事を書きました。今回は使い方になります。

使い方

使用するコードは、デフォルトのJSON タイプとしてNewtonsoft.Jsonを使用します。

参照

JSON定数

変数をXML定数で初期化できるように、ModVBはJSON定数で変数の初期化をサポートしており、その使用法はXML定数と多少似ています。
たとえば、NuGetツールバージョンのクエリ結果のスニペットを見てみましょう。
https://dist.nuget.org/tools.jsonリクエストは、次のようなJSONを取得して変数に格納できます。

Module Program

    Sub Main()
        Dim latestVersion = "6.3.0"
        Dim stableVersions = {
            (ver:="6.2.1", uploaded:="2022-06-14T17:00:00.0000000Z"),
            (ver:="6.2.0", uploaded:="2022-05-10T13:00:00.0000000Z"),
            (ver:="6.1.0", uploaded:="2022-02-15T13:00:00.0000000Z")
        }

        Dim nugetVersions = {
            "nuget.exe": [
                {
                    "version": latestVersion,
                    "url": $"https://dist.nuget.org/win-x86-commandline/v{latestVersion}/nuget.exe",
                    "stage": "Released",
                    "uploaded": "2022-08-09T13:00:00.0000000Z"
                },
                From verInfo In stableVersions
                Select {
                    "version": verInfo.ver,
                    "url": $"https://dist.nuget.org/win-x86-commandline/v{verInfo.ver}/nuget.exe",
                    "stage": "ReleasedAndBlessed",
                    "uploaded": verInfo.uploaded
                }
            ]
        }

        Console.WriteLine(nugetVersions)
    End Sub
End Module

このコードを実行した結果は次のとおりです。

実行結果
{
  "nuget.exe": [
    {
      "version": "6.3.0",
      "url": "https://dist.nuget.org/win-x86-commandline/v6.3.0/nuget.exe",
      "stage": "Released",
      "uploaded": "2022-08-09T13:00:00.0000000Z"
    },
    {
      "version": "6.2.1",
      "url": "https://dist.nuget.org/win-x86-commandline/v6.2.1/nuget.exe",
      "stage": "ReleasedAndBlessed",
      "uploaded": "2022-06-14T17:00:00.0000000Z"
    },
    {
      "version": "6.2.0",
      "url": "https://dist.nuget.org/win-x86-commandline/v6.2.0/nuget.exe",
      "stage": "ReleasedAndBlessed",
      "uploaded": "2022-05-10T13:00:00.0000000Z"
    },
    {
      "version": "6.1.0",
      "url": "https://dist.nuget.org/win-x86-commandline/v6.1.0/nuget.exe",
      "stage": "ReleasedAndBlessed",
      "uploaded": "2022-02-15T13:00:00.0000000Z"
    }
  ]
}

上記の例で、nugetVersionsの変数を抽出できます。
JSON定数は、オブジェクト階層を深くすることなく、複数のJSONオブジェクトを1つにマージするために使用できるフラット化操作をサポートします。

次のコードは最初のバージョン情報から2つの属性を変数に抽出し、残りのバージョン情報から別の変数を抽出します。
プログラムの実行結果は上記と変わりません。

Module Program

    Sub Main()
        Dim latestVersion = "6.3.0"

        Dim stableVersions = {
            (ver:="6.2.1", uploaded:="2022-06-14T17:00:00.0000000Z"),
            (ver:="6.2.0", uploaded:="2022-05-10T13:00:00.0000000Z"),
            (ver:="6.1.0", uploaded:="2022-02-15T13:00:00.0000000Z")
        }

        Dim stable = From verInfo In stableVersions
                     Select {
                      "version": verInfo.ver,
                      "url": $"https://dist.nuget.org/win-x86-commandline/v{verInfo.ver}/nuget.exe",
                      "stage": "ReleasedAndBlessed",
                      "uploaded": verInfo.uploaded
                    }

        Dim releasedStage = {
            "stage": "Released",
            "uploaded": "2022-08-09T13:00:00.0000000Z"
        }

        Dim nugetVersions = {
            "nuget.exe": [
                {
                    "version": latestVersion,
                    "url": $"https://dist.nuget.org/win-x86-commandline/v{latestVersion}/nuget.exe",
                    {releasedStage}
                },
                stable
            ]
        }

        Console.WriteLine(nugetVersions)
    End Sub

End Module

JSON パターン マッチング

JSON パターンマッチングは、JSONの構造や内容を判断しながら、必要な情報を変数に抽出することができます。


JSON 定数の例で JSON を例に取ります。
例えば、stableReleasedAndBlessedであるnuget.exeのすべてのバージョンとその他の情報を取得する必要があるとします。
次のコードを使用できます。

上記のJSON定数コードの続きに記述してください。

    Console.WriteLine("リリース済みのすべての安定版:")

    Select Case ShapeOf nugetVersions
        Case {"nuget.exe": nodes}
            For Each node In nodes
                Select Case ShapeOf node
                    Case {
                        "version": ver As Version,
                        "url": url As String,
                        "stage": "ReleasedAndBlessed",
                        "uploaded": relaseDate As Date
                    }

                    Console.WriteLine($"{ver} リリース {relaseDate:F}, ダウンロード先 {url}")
                End Select
            Next
    End Select

コンソール

出力結果
リリース済みのすべての安定版:
6.2.1 リリース 2022年6月15日 2:00:00, ダウンロード先 https://dist.nuget.org/win-x86-commandline/v6.2.1/nuget.exe
6.2.0 リリース 2022年5月10日 22:00:00, ダウンロード先 https://dist.nuget.org/win-x86-commandline/v6.2.0/nuget.exe
6.1.0 リリース 2022年2月15日 22:00:00, ダウンロード先 https://dist.nuget.org/win-x86-commandline/v6.1.0/nuget.exe

Select Case ShapeOf ステートメント

Select Case ShapeOfは、Select Case内のCaseの意味を変え、通常のSelect Caseの構文と矛盾することなくパターンマッチを行うことができる、パターンマッチに特化したSelect Caseです。

JSON オブジェクトに一致
JSONオブジェクトのマッチングには、以下のコードのように、JSONマッチパターンを中括弧で囲む必要があります。

Case {
    "属性1": "値1",
    "属性2": "値2",
    "属性3": null,
    "属性4"?: "null可能属性"
  • マッチングの順番は列の上から下、左から右の順です。コードでは、属性1が先にマッチングされ、属性2が後にマッチングされる。
  • 属性を除外するには、値がNULLの属性にマッチさせることができます。この図では、属性3が空であることを要求しています。このようにJSONは属性3を書かないか、属性3をNULLで書くことで一致させる。
  • コロンの左側にクエスチョンマークが書かれている場合、そのプロパティが空でもマッチします。コード中の属性4は空でもよい。これには、属性が書き込まれていない場合や、属性値がNULLで書き込まれている場合も含まれる。
  • JSONに別の属性があり、その属性のマッチングルールが中括弧の中に書かれている場合、残りの属性はマッチング結果に影響を及ぼさない。
    中括弧の中に何も書かれていない場合は、空のJSONオブジェクトのみがマッチングされます。

JSON配列に一致

JSON配列のマッチングには、下コードのように、JSONマッチパターンを2つの括弧で囲むことが必要です。

Case [ "要素1", "要素2", 345, true, false, null ]
  • 上コードの意味は,少なくともこれらの要素が指定された配列の先頭から順に, "要素1", "要素2", 345, true, false, null とマッチすることです. もし配列が予想より長くなっても,マッチは成功します.
  • 括弧の中に何も書かれていない場合は、空の配列のみがマッチングされる。

JSON定数に一致

ここでは、VBの定数式であれば何でも使用できます。JSON定数(true, false, null)も使用可能です。

変数の種類によるマッチングと定義

Case {
    "属性1": value1 As Version,
    "属性2": value1 As String,
    "属性3": value3
    }
  • 値がNULLでなく、指定された型に変換できる場合、マッチする。
  • この変換では、TryCast、VBの組み込み変換ルール、およびTryParseなどの他の変換方法が考慮されます。
  • コードのプロパティ1は、JSONコンテンツを文字列として解析し、TryParseを試行します。
  • コード中のプロパティ2は、JSONを文字列として解析します。
  • コードのプロパティ3は、プロパティ3が空でなければ、JSONの値をそのまま返します。

疑問符を使用してオプションであることを示します

基本的にすべてのパターンマッチング式は、最後にクエスチョンマークを書くことができ、それによって式がNULLにもマッチするようになります。ここでは、属性undefinedと値nullは同じケースと見なします。以下にいくつかの例を示します。

nullになる可能性のあるオブジェクトにマッチする

Case {
    "属性1": "値1",
    "属性2": "値2"
    }?

null 許容値に一致する

Case {
    "属性1": "値1",
    "属性2": "値2"?
    }

属性1は空にすることができ、属性2は属性に一致して変数を定義し、属性値は空にすることができます。

Case {
    "属性1": [ "値1" ]?,
    "属性2": value1?
    }

属性値が空の場合、定義された変数にはデフォルト値があります。

ランタイム拡張機能とAPIの互換性

JSONの定数とパターンマッチは、LINQFor Eachループと同様、パターンベースです。
特定のライブラリやタイプに縛られることはありません。
これらの関数は、コードの解析やコンパイル時に、特定の名前空間からメンバを使用して適格な型を検索します。
ModVBコンパイラを含むパッケージをインストールするだけで、特定のパターンマッチング拡張を自分で記述することも可能です。
JSON定数やパターンマッチを使用しているプロジェクトをデコンパイルすることで、JSON定数拡張パッケージやパターンマッチ拡張パッケージの書き方を学ぶことができます。

最後に

この記事は下記のModVB紹介記事を参考にDeepLなどを駆使して書きました。

ModVBでは、このように拡張機能で使えるようになります。今回はWave1のみです。
今後のModVBの機能強化に期待しましょう。

ModVBの機能予定

現時点(2022/12/22)では、Wave 1は今年の夏にリリースされました。WAVE 2が12月予定とのことでしたが、まだ未リリースです。

バージョン 機能内容
Wave 1 JSON リテラルとパターン マッチングを中心に展開
Wave 2 XML リテラルの強化
Wave 3 不明 Wave 2 と Wave 4の中間の機能強化
Wave 4 Async ストーリー強化
Wave 5 LINQ のより深い統合
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?