「オープンソース – 拡張ライブラリ」カテゴリーアーカイブ

拡張ライブラリ v0.7 / v0.8 概要

Curl拡張ライブラリは、ユーティリティ機能をはじめとして、コレクション操作、ロギング、キャッシング、入出力などのコンポーネントが多数含まれています。これはオープンソース(Apache License2.0)として提供しており、SourceForgeからダウンロードできます。

具体的には以下のコンポーネントが梱包されています。

LANG
– ユーティリティ:String, Number, DateTime, Unit (Distance, Time), Reflection, only-if, a few switch (since0.7)

COLLECTIONS
– ユーティリティ:Array, HashTable
– コレクションクラス:MultiHashTable, MultiKeyHashTable, OrderedHashTable, OrderedSet
– マクロ:collect, range

UI
– 2度押し防止, DTO from/to Controls, Graphic検索

CACHING
– メモリキャッシュ, キャッシュのディスク保存

DATA-ACCESS
– ユーティリティ:RecordSet, RecordData

CODEC
– hex-encode, hex-decode

Messages
– MessageList

UTIL
– diff (since0.7)
– stop-watch
– Properties

ENVIRONMENT
– environment-switch, if-local-applet, IP・ホスト名取得

CRYPTO
– MD5, SHA-1, HMAC-SHA-1(since0.7), DES3, RC2, RC4

JAPAN
– 郵便番号、都道府県

MATH
– 数学関数

IO
– ディレクトリ検索
– 圧縮・解凍, オブジェクト保存・復元, RecordSet保存・復元

LOGGING
– ログ取得, ログローテート

注意)バージョン0.7からCurl6.0及び7.0に対応されています。0.8からはCurl8.0に対応されています。

いくつかのswitch文

switch文を拡張した、新たなswitchマクロがバージョン0.7から追加されました。

■正規表現による文字列のスイッチ文

            def str = “Curl is great, I like Curl”
            {regexp-switch str
             case “^Curl.*Curl$” do
                {output strは正規表現^Curl.*Curl$に一致。}
             case “^Java.*Java$”, “^Ruby.*Ruby$” do
                {output strは正規表現^Java.*Java$もしくは^Ruby.*Ruby$に一致。}
             else
                {output str}
            }

■文字列の先頭文字によるスイッチ文(この逆でsuffix-switchもあります。)

            def str = “abcdef”
            {prefix-switch str, ignore-case? = true
             case “abc” do
                {output strはabcから始まります。}
             case “xyz”, “xxx” do
                {output strはxyzもしくはxxxから始まります。}
             else
                {output str}
            }

■数値の範囲によるスイッチ文

            def i = 50
            def result =
                {range-switch i
                    case 0 to 20 do “Too bad”
                    case 26 to 50 do “Bad”
                    case 51 to 75 do “Not bad”
                    case 75 to 99 do “Good”
                    case 100 do “Excellent”
                    case 101 to 200, 400 to 600 do “Strange!?”
                    else {unreachable}
                }
            {output result} || ==> “Bad”

注意)バージョン0.7からサポートされます。

 

diffプロシージャ(文字列の差分)

diffコマンドのような文字列の差分を比較するプロシージャがCOM.CURLAP.LIB.UTILパッケージに含まれます。

これは以下のサンプルように利用することができます。

 

            {diff
                “map”, “apple”,
                {fn ses, o, n, p1, p2 =>
                    {switch ses
                     case ShortestEditScript.common do
                        {output “common:” & o}
                     case ShortestEditScript.added do
                        {output “appended:” & n}
                     case ShortestEditScript.deleted do
                        {output “deleted:” & o}
                    }
                }
            }

比較する引数を第1と第2引数に指定し、比較した1文字ごとに第3引数のプロシージャが実行されます。このプロシージャの1個目の引数で、2つの文字列内で共通した文字か、削除されたものか、追加されたものかを判断できます。このサンプルの場合、apが共通、mが削除、pleが追加された文字と認識されます

注意)バージョン0.7からサポート

Curl Lib APIリファレンスのインストール

APIリファレンスのCurlのドキュメントに追加するには、以下の手順で実施します。

  1. Curl Libをダウンロードします。(curl-lib_0.5_bin.zipをダウンロードしてください。)
  2. Curl IDEを起動
  3. メニューからヘルプ→ドキュメンテーションのインストールを選択
  4. インストールボタンを押下し、ダウンロードしたファイルの展開後のディレクトリから、COM.CURLAP.LIB.mcurlを選択します。
  5. ダイアログの一覧にCOM.CURLAP.LIBが追加されます。

これで、APIリファレンスを利用することが可能となります。
(Curl ドキュメント・ビューワを開き、目次の一覧からCOM.CURLAP.LIBを参照)

 

Curl Lib利用方法

Curl Libをプロジェクトで利用するには、以下の手順でデリゲートする必要があります。

  1. Curl Libをダウンロードし、展開する。
  2. Curl IDEで、メニューからプロジェクト→デリゲート先の追加を選択。
  3. 展開したCurl LibディレクトリのCOM.CURLAP.LIB/manifest.mcurlを選択し、開くボタンを押下。

これで、Curl LibのAPIが利用できます。(もちろん、importはしてください。)

 

 

Array、配列(FastArray)ユーティリティ

ArrayUtil

Array-ofやFastArray-ofのユーティリティとして、ArrayUtilというクラスがあります。これを用いることで、標準APIには含まれないAPIを利用することが可能となります。

ArrayUtil.output

Arrayの全データを出力します。

        def x = {{Array-of String} “apple”, “orange”, “pine”}
        {ArrayUtil.output x}

#{apple orange pine}と表示されます。

ArrayUtil.unique / ArrayUtil.unique-clone

Array内のデータで重複をなくします。例えば、”apple”, “orange”, “pine”, “orange”, “pine”という5つのデータが存在する場合、重複を排除し、、”apple”, “orange”, “pine”という3つになります。

        def x = {{Array-of String} “apple”, “orange”, “pine”, “orange”, “pine”}
        {ArrayUtil.unique x} || -> “apple”, “orange”, “pine”

ArrayUtil.contains?

Array内にデータが含まれるか否かをチェックします。

        def x = {{Array-of String} “apple”, “orange”, “pine”, “orange”, “pine”}
        {ArrayUtil.contains? x, “apple”} || -> true

ArrayUtil.grep / ArrayUtil.grep-clone

Array内のデータを正規表現にマッチするものだけに絞り込みます。

        def x = {{Array-of String} “a01”, “a02”, “b01”, “b02”, “c01”}
        {ArrayUtil.grep x, “a.*”} || -> “a01”, “a01”

似たようなAPIでArrayUtil.filter-by-prefixやArrayUtil.filter-by-suffixというものがあります。詳細はCurlドキュメンテーションを参照ください。

ArrayUtil.max / ArrayUtil.min / ArrayUtil.sum / ArrayUtil.avg

Arrayの中の最大値、最小値、合計、平均を結果として返します。

        def x = {{Array-of int} 1, 2, 3, 4, 5}
        {ArrayUtil.max x} || 5
        {ArrayUtil.min x} || 1
        {ArrayUtil.sum x} || 15
        {ArrayUtil.avg x}  || 3

その他、Array-of、FastArray-ofのための便利APIが多く用意されています。詳細は、Curlドキュメンテーションをインストールしてご参照ください。(例えば、和集合、差集合などのunion / union-all / intersect / minusなど)

パッケージ名:COM.CURLAP.LIB.COLLECTIONS 

Stringユーティリティ(日本語、文字列操作など)

StringUtilユーティリティ

StringUtil.hiragana-to-katakana / StringUtil.katakana-to-hiragana

ひらがな・カタカナ変換、カタカナ・ひらがな変換

{StringUtil.hiragana-to-katakana “ぱぴぷぺぽ”} || == “パピプペポ”
{StringUtil.katakana-to-hiragana “パピプペポ”} || == “ぱぴぷぺぽ”

StringUtil.full-to-half / StringUtil.half-to-full

全角・半角変換、半角・全角変換

{StringUtil.full-to-half “qwertyuiopasdfghjklzxcvbnm”} || == “qwertyuiopasdfghjklzxcvbnm”
{StringUtil.half-to-full “qwertyuiopasdfghjklzxcvbnm”} || == “qwertyuiopasdfghjklzxcvbnm”

StringUtil.rjust / StringUtil.pad-right

文字のパディングをします。 

{StringUtil.pad-right “abc”, 5} ||== “abc00”

{StringUtil.rjust “abc”, 5, padding = ‘0’} || == “abc00”

StringUtil.separate-by-name

文字列を分割します。その他、指定位置で分割するStringUtil.separateプロシージャなどもあります。

def (h1, t1) = {StringUtil.separate-by-char “key=value”, ‘=’}
|| h1 == “key”
|| t1 == “value”

StringUtil.insert

文字列の指定位置に新たな文字列を埋め込むことができます。

{StringUtil.insert “20090910”, “/”, 4, 6} ||== “2009/09/10”

そのStringUtilには豊富なAPIが備わっています。詳しくはCurlドキュメンテーションをインストールし、ご参照ください。

パッケージ名:COM.CURLAP.LIB.LANG

DateTimeユーティリティ(和暦・西暦変換、うるう年など)

DateTimeユーティリティ

拡張ライブラリのDateTime(日付型)のユーティリティ群です。

DateTimeUtil.is-uruu?

うるう年か否かをチェック

{DateTimeUtil.is-uruu? 2004}

DateTimeUtil.add / DateTimeUtil.minus / DateTimeUtil.modify

日付の足し算、引き算、修正

        || add
        {DateTimeUtil.add mon, day = 3}

        || minus
        {DateTimeUtil.minus mon, day = 2}
        {DateTimeUtil.minus mon, day = 1}
        
        || modify
        {DateTimeUtil.modify mon, day = 5}

DateTimeUtil.wareki-to-seireki / DateTimeUtil.seireki-to-wareki

和暦・西暦変換 

{DateTimeUtil.wareki-to-seireki Wareki.heisei, 21} || 2009

set (wareki1, nen1, wareki2, nen2) = {DateTimeUtil.seireki-to-wareki 1988}
 || wareki1 == Wareki.syouwa
 || nen1 == 63
 || wareki2 == Wareki.undefined
 || nen2 == -1

DateTimeUtil.elapsed-days / DateTimeUtil.elapsed-hours

経過時間(2つのDateTimeの差分)

def dt1 = {DateTime year = 2008, month = 1, day = 1}
def dt2 = {DateTime year = 2008, month = 2, day = 1}
{DateTimeUtil.elapsed-days dt1, dt2} ||== 31
 
def dt1 = {DateTime year = 2008, month = 1, day = 1, hour = 0}
def dt2 = {DateTime year = 2008, month = 1, day = 1, hour = 12}
{DateTimeUtil.elapsed-hours dt1, dt2} ||== 12

DateTimeUtil.last-day-of-month

DateTimeの月末を取得

def dt = {DateTime year = 2009, month = 2, day = 2}
{DateTimeUtil.last-day-of-month dt} || == 2009年2月28日

その他、便利APIが多く用意されています。詳細は、Curlドキュメンテーションをインストールしてご参照ください。

パッケージ名:COM.CURLAP.LIB.LANG

 

RecordSetユーティリティ

 

RecordSetやRecordField、RecordData、Recordに対する操作は多くのロジックで使われます。そのため、ユーティリティを作成しました。

RecordSetUtil

RecordSetUtil.append-arrays / RecordSetUtil.append-hashtables

RecordSetにArrayデータを追加します。(HashTableデータを追加する場合は、append-hashtablesを使います。)

        def rs = {RecordSet
                     {RecordFields
                         {RecordField “col1”, domain = int},
                         {RecordField “col2”, domain = String}
                     }
                 }
        def data1 = {{Array-of Array}
                        {Array 1, “test1”},
                        {Array 2, “test2”},
                        {Array 3, “test3”}
                    }
        {RecordSetUtil.append-arrays rs, data1}

RecordSetUtil.to-arrays / RecordSetUtil.to-hashtables

上記とは逆にRecordSetからArrayデータを生成します。(HashTableデータを生成する場合は、to-hashtablesを使います。)

def arrays = {RecordSetUtil.to-arrays rs}

RecordSetUtil.write-to-stream

RecordSetをOutputStreamに書き出します。

    {with-open-streams
        out = {SerializeOutputStream
                  {write-open-byte
                      url,
                      create? = create?,
                      create-mode = create-mode,
                      error-if-exists? = error-if-exists?
                  }
              }
     do
        {RecordSetUtil.write-to-stream out, rs}
    }

逆に呼び出す場合は、read-from-streamを利用します。

その他にも、RecordSetUtilにAPIがあります。詳細は、Curlドキュメンテーションをインストールして、ご参照ください。

RecordFieldUtil

RecordFieldUtil.auto-increment

MySQLなどが持つ、自動的に数値をカウントアップしてくれる機能であるauto_incrementを以下のように記述できます。

        def rs = {RecordSet
                     {RecordFields
                         {RecordField
                             “col1”, domain = int,
                             default-value = {RecordFieldUtil.auto-increment}
                         },
                         {RecordField
                             “col2”, domain = String
                         }
                     }
                 }

その他にも、RecordFieldUtilにAPIがあります。詳細は、Curlドキュメンテーションをインストールして、ご参照ください。

RecordDataUtil

RecordDataUtil.create

普通のクラスからRecordDataを生成します。(クラスのフィールド名がRecordFieldのカラム名となります。) 下記サンプルではFooクラスからRecordDataを生成しています。

{define-class public Foo
  field public col1:int
  field public col2:String
  field public col3:DateTime

  {constructor public {default col1:int, col2:String, col3:DateTime}
    set self.col1 = col1
    set self.col2 = col2
    set self.col3 = col3
  }
}

 

def rs = {RecordSet
                {RecordFields
                     {RecordField “col1”, domain = int},
                     {RecordField “col2”, domain = String},
                     {RecordField “col3”, domain = DateTime}
                }
           }
def foos =
      {{Array-of Foo}
           {Foo 1, “val1”, {DateTime year=2009, month=1, day=1}},
           {Foo 2, “val2”, {DateTime year=2009, month=2, day=2}},
           {Foo 3, “val3”, {DateTime year=2009, month=3, day=3}}
      }
{for foo in foos do
       {rs.append {RecordDataUtil.create foo}}
}

 

RecordUtil

RecordUtil.set-valeu

RecordDataUtil.createとは逆に、Recordの値をFooクラスなどのデータクラスのフィールドへ値をセットします。

        {for r in rs do
            def foo = {Foo 0, “”, {DateTime year=2008, month=1, day=1}}
            {RecordUtil.set-values r, foo}
        }

その他にも、RecordUtilにAPIがあります。詳細は、Curlドキュメンテーションをインストールして、ご参照ください。

パッケージ名:COM.CURLAP.LIB.DATA-ACCESS

 

HashTableユーティリティ

HashTableUtil

HashTable-ofのユーティリティとして、HashTableUtilというクラスがあります。これを用いることで、標準APIには含まれないAPIを利用することが可能となります。

HashTableUtil.output

HashTableの全データを出力します。

        def x = {{HashTable-of int, String} 1, “apple”, 2, “orange”, 3, “pine”}
        {HashTableUtil.output x}

1=apple
2=
orange
3=pine
と表示されます。

HashTableUtil.concat

2つのHashTableを結合します。 

        def h1 = {{HashTable-of int, String} 0, “apple”, 1, “banana”}
        def h2 = {{HashTable-of int, String} 2, “orange”, 3, “banana”, 0, “pine”}
        {HashTableUtil.concat h1, h2}

その他、HashTable-ofのための便利APIが多く用意されています。詳細は、Curlドキュメンテーションをインストールしてご参照ください。

パッケージ名:COM.CURLAP.LIB.COLLECTIONS 

マルチキーHashTable

拡張ライブラリの中に、複数のキーを保持できるHashTableクラスが含まれています。

MultiKeyHashTable-2-of クラス

複数のキー(2個)を保持できるHashTableです。 

        def hash1 = {{MultiKeyHashTable-2-of String, int, String}
                        “k1”, 10, “apple”,
                        “k2”, 10, “banana”
                    }
        {hash1.set “k3”, 20, “orange”}  || セット
        set hash1[“k4”, 20] = “blueberry”  || セット

        def v1 = {hash1.get “k1”, 10, 20} || ゲット
        def v2 = hash1[“k2”, 10, 30] || ゲット
       

MultiKeyHashTable-3-of

複数のキー(3個)を保持できるHashTableです。使い方はMultiKeyHashTable-2-ofとキーの数以外は同等です。

MultiHashTable-of

キーは1つですが、重複したキーを保持できるHashTableです。 

        def hash = {{MultiHashTable-of String, String}
                       “k1”, “apple”, “k2”, “banana”, “k1”, “blueberry”, “k1”, “melon”
                   }
        def val-array = {hash.get “k1”} || キーが”k1″の値すべて返ってきます。

パッケージ名:COM.CURLAP.LIB.COLLECTIONS 

順序HashTableと順序Set

OrderedHashTable-of

通常のHashTableは順番を持ちませんが、OrderedHashTable-ofは順序を持ちます。順番(ID)から値を取得するには、get-by-indexメソッドを利用します。

        def hash = {{OrderedHashTable-of String, String}
                       “k1”, “apple”, “k2”, “banana”, “k3”, “blueberry”
                   }
        {hash.set “k4”, “melon”}
       
        let (key:String, value:String) = {hash.get-by-index 0}
        set (key, value) = {hash.get-by-index 1}

 

 

OrderedSet-of

OrderedSet-ofは順序を持ったSet-ofです。こちらも同様に、順番(ID)から値を取得するには、get-by-indexを利用します。 

        def s = {{OrderedSet-of String} “apple”, “banana”, “orange”}
        let v:String = “”
       
        set v = {s.get-member-by-index 0}
        set v = {s.get-member-by-index 2}

パッケージ名:COM.CURLAP.LIB.COLLECTIONS 

 

 

 

arrayマクロを利用した簡単Array-of定義

Array-ofやFastArray-ofは型パラメータが必要なため記述量が多くなってしまいます。arrayマクロとfast-arrayマクロは型パラメータの記述を省略して配列を生成するためのマクロです。

arrayマクロ

このマクロは、与えられた初期値から型パラメータを推測して、適切な Array-of 配列の定義に置換されます。

|| 従来の書き方
def x = {{Array-of int} 1, 2, 3}

|| arrayマクロ利用(パラメータがintと推測されます)
|| 以下は上記と同等です。

def x = {array 1, 2, 3}

また、コンパイル時型の異なる引数が与えられた場合も、なるべく具体的な型の配列の生成を試みます。以下はサンプルです。

def x = {array {TextField}, {PasswordField}, {ComboBox}}

これは{Array-of any}ではなく、{Array-of {MultiUIValueControlFrame-of String}}となります。

fast-arrayマクロ

これはarrayマクロのFastArray-of版です。

 

 

hashtableマクロを利用した簡単HashTable-of定義

HashTable-ofの定義はジェネリクスを記述しないといけないので、ちょっとめんどくさいという方のために、hashtableマクロを提供します。この機能はarrayマクロと類似しています。

hashtableマクロ

このマクロは、初期値を与えると、その初期値からジェネリクスを推測し、型定義を自動的にしてくれます。

|| 従来の書き方
def x = {{HashTable-of String, int} “k1”, 1, “k2”, 2, “k3”, 3}

|| hashtableマクロ利用(Stringとintというジェネリクスを推測してくれます。)
|| 以下は上記と同等です。

def x = {hashtable “k1”, 1, “k2”, 2, “k3”, 3}

また、コンパイル時型の異なる引数が与えられた場合も、なるべく具体的な型の配列の生成を試みてくれます。以下はサンプルです。

def x = {hashtable {TextField}, 1, {PasswordField}, 2, {ComboBox}, 3}

これは{HashTable-of any, int}を返すのではなく、{HashTable-of {MultiUIValueControlFrame-of String}, int}を生成します。

 

 

collectマクロを利用したArray生成

collectマクロ

コンテナ (Array-of、HashTable-of, Set-of、 String、列挙型など) から新しい配列(Array-of オブジェクト) を生成します。生成される配列の要素型はコンパイル時に決定されます。

以下の例で、resultsは numbers の各要素を 1.5 倍した要素からなる{Array-of double} になります。

def numbers = {{Array-of int} 0, 5, 10, 15}
def results = {collect n in numbers do
                        n * 1.5
                   }

以下の例は、continue を使用して結果の配列に含める要素を選別しています。 

def numbers = {{Array-of int} 0, 1, 2, 3, 4, 5}
def results = {collect n in numbers do
                         || 偶数は含めない
                         {if (n mod 2) == 0 then
                               {continue}
                         }
                         n
                  }

パッケージ名:COM.CURLAP.LIB.COLLECTIONS 

ログ出力とログ・ローテーション

ログ出力

Log4jやcommons loggingのようなロギング機能です

initialize-logプロシージャで、ロギング機能の設定をセットします。そのあと、以下のように利用します。

def logger = {LogFactory.get-log}

{logger.fatal “致命的エラーです。”}
{logger.error “エラーです。”}
{logger.warn “ワーニングです。”}
{logger.info “情報です。”}
{logger.debug “デバッグです。”}
{logger.trace “トレースです。”}

ログ・ローテーション

rotate-logプロシージャを利用して、Apache LogRotateのように、ローテーションができます。

詳細については、Curlドキュメンテーションを参照ください。

パッケージ名:COM.CURLAP.LIB.LOGGING

envrironment-switchで実行モードの切り替え

environment-switch

これは、開発時、テスト時、本番時ごとに処理を変えたい場合に、切り替えることのできるマクロです。

例えば下記の例は、”development”, “test”, “production”という環境ごとにincludeするファイルを変更したい場合に以下のようにコーディングできます。 

{environment-switch
    case “development” do
      {include “foo-dev.scurl”}
    case “test” do
      {include “foo-test.scurl”}
    case “production” do
      {include “foo.scurl”}
    else
}

全体の設定として、”development”, “test”, “production”を指定するには、manifest.mcurlファイルにx-environmentというキーワードを記述します。

{curl 6.0 manifest}
{manifest TESTS,
    x-environment = “development”
}

この例ですと、”development”というモードで稼動しますので、environment-switchの”development”が実行され、”foo-dev.scurl”がincludeされます。

ちなみに、”development”, “test”, “production”などは、任意の文字列が指定できます。

パッケージ名:COM.CURLAP.LIB.ENVIRONMENT

 

データ・キャッシング

キャッシング機能

javaで有名なJCacheやEHCacheなどのように、クライアントでのキャッシングができます。これらは、例えばほとんど変わらないマスタデータを毎回サーバに取得するのではなく、一定期間、メモリもしくはディスクにキャッシングしておき、サーバ負荷を軽減するために利用できます。

まずは、キャッシュという1つの塊をCacheManager.create-cacheメソッドにて作成します。このとき、キャッシュ内の各オブジェクトの生存期限、キャッシュの最大数などを指定できます。最大数を越えた場合は、一番アクセスされていないオブジェクトを破棄します。 

        || キャッシュの作成
        def cm = {CacheManager.get-instance}
        def cache1 = {cm.create-cache
                         “cache1”,
                         max-elements-in-cache = 3,
                         expire-idle-time = 1s
                     }
        || キャッシュ”cache1”にオブジェクト登録
        {cache1.set “k1”, {Array}}
        {cache1.set “k2”, {HashTable}}
        {cache1.set “k3”, 10}

        || キャッシュからオブジェクト取得
        def v = cache1[“k1”]

メモリ上にあるキャッシュをディスクへ書き出すには、キャッシュ作成時にpersistent-disk引数にURLを指定しておくと、flushメソッドを実行した場合にディスクへ書き出します。 

        def cm = {CacheManager.get-instance}
        def cache =
            {cm.create-cache “disk-cache”, persistent-disk = {url “file/disk.cache”}}
        set cache[“k1”] = “val1”
        set cache[“k2”] = “val2”
        {cache.flush} || persistent disk

もうちょっと簡単にキャッシュを利用するために、with-cacheマクロが利用できます。このマクロは、もしキャッシュ内にオブジェクトがなければ、with-cacheの中身が実行され、結果がキャッシュへ格納され、戻り値を返します。キャッシュ内にオブジェクトがある場合、キャッシュから取得した値を戻します。

        def v1 =
            {with-cache “k1” of “cache1” do
                def v = “test”
                v
            }

パッケージ名:COM.CURLAP.LIB.CACHING

メッセージ・リソースファイル

ほとんどのアプリケーションで利用されるメッセージ・リソースファイルのためのAPIです。

このAPIでは、メッセージを管理し、アプリケーション内からメッセージを取得することができます。以下にメッセージAPI(MessageList)のサンプルを掲載しておきます。

|| メッセージ定義(通常はメッセージファイルとして管理)
def messages = {MessageList
                           “MSG01”, “あいうえお”,
                           “MSG02”, “Hello %s!”
                       }

|| “あいうえお”が取得できます。
{messages[“MSG01”].create-message}

|| Hello Curl!が取得できます。
{messages[“MSG02”].create-message “Curl”}

詳細は、COM.CURLAP.LIB.MESSAGESパッケージを参照してください。