0
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 3 years have passed since last update.

スクリプト言語 KINX/【雑多なこと】その後サポートした機能

Last updated at Posted at 2020-03-05

はじめに

見た目は JavaScript頭脳(中身)は Ruby、(安定感は AC/DC)」になっているかはさておき。

解説ばっかりで疲れてきたので、解説とは別に雑多な話題をご提供。いくつか機能をサポートしました。ドキュメントをそろえてバージョン 1 を何とかリリースしたいところ。

その後サポートした機能

構文的な追加とライブラリの追加をしました。

構文

module

modulemixin という予約語で、後から機能をアタッチできる仕組み。

module Printable {
    public print() {
        System.print(@value); // `this` is not Printable's instance but host class's instance.
                              // In this case, this means Value's instance.
    }
    public println() {
        System.println(@value);
    }
}

class Value(v) {
    mixin Printable;
    private initialize() {
        @value = v;
    }
}

var v = new Value(100);
v.println();    // 100

namespace

名前空間。クラスとモジュールは自動的に名前空間に属し、名前空間を経由してアクセス可能。

namespace Name1 {

    class X {
        public methodX() {
            System.println("x1");
        }
    }

    var x = new X();
    x.methodX(); // x1

    namespace Name2 {
        class X {
            public methodX() {
                System.println("x2");
            }
        }

        var x = new X();
        x.methodX(); // x2
    } // namespace Name2

} // namespace Name1

var x1 = new Name1.X();
x1.methodX(); // x1

var x2 = new Name1.Name2.X();
x2.methodX(); // x2

ライブラリ

下記のサンプルはリポジトリ にもコミットしてある。

Zip

Zip による圧縮・解凍をサポート。試してないが、使ったライブラリの説明によれば Zip64 もいける(自動的に対処される)はず。WinZIP の AES アルゴリズムには対応されているのを確認した。ただし、AES 暗号化を有効にしてしまうと Windows の Explorer で解凍できなくなるが強固にはなる。こんな感じ。

import Zip;

var zip = new Zip("examples/zip/ziptest.zip", File.READ|File.WRITE);
zip.setPassword("text");
zip.addFile("README.md", {
    method: "bzip2",
    aes: true,
});
zip.addFile("README.md");
zip.addString("test/test1.txt", {
    content: "test/test\n",
    aes: true,  // Can not use aes option for addString, that means no effect for addString.
});
zip.addString("test/test2.txt", {
    content: "test/test\n",
    password: "text2",
});

System.println("totalFiles = ", zip.totalFiles);
zip.each(function(e) {
    System.println("%s:" % e.filename);
    e.keySet().each(&(key) => {
        if (e[key].isFunction || e[key].isObject || e[key].isUndefined) {
            return;
        }
        if (key == "crc32") {
            System.println("    %-14d = %10X" % key % e[key]);
        } else if (key != "time" && key != "filename") {
            System.println("    %-14d = %10d" % key % e[key]);
        }
    });
    e.time.keySet().each(&(k) => {
        System.println("      time.%-7d = %10d" % k % e.time[k]);
    });
    // if (e.filename == "README.md") {
    //     e.extractTo("READMEXX.md", { password: "text", overwrite: true });
    // }
});

var file = zip.read("README.md", { password: "text" });
System.println(file);
zip.find("README.md")
    .extractTo("READMEXX.md", { password: "text", skip: true });

SQLite3

SQLite3 データベースの読み書きをサポート。トランザクションもサポート。何か他にも気にするところがあったような。。。SQLITE_BUSY が返ってきたときの挙動とかかな。追々確認しよう。今はこんな感じ。

import SQLite;

var db = new SQLite("database.db", 3000);
db.exec("CREATE TABLE IF NOT EXISTS mytable "
    "("
        "id INTEGER PRIMARY KEY AUTOINCREMENT, "
        "name TEXT NOT NULL"
    ")"
);
db.transaction(&{
    var ins = db.prepare("INSERT INTO mytable (name) VALUES (?)");
    for (var i = 0; i < 20; ++i) {
        ins.bind("name(%{i})").exec();
    }
});

var c, r = db.prepare("SELECT * FROM mytable WHERE (id > ? AND id < ?) OR id = ?")
            .bind(2)
            .bind(8, 10)    // bind() can be separated.
            .query();       // do binding & ready to next().

while (c = r.next()) {
    var cols = c.columnName;
    var vals = c.value;
    System.println("Record[%d]" % vals[0]);
    for (var i = 0, len = cols.length(); i < len; ++i) {
        System.println("    %-8s = %s" % cols[i] % vals[i]);
    }
}

Xml

Xml 文書の読み書きをサポート。XPath も使える。ちょっと長いがこんな感じ。

import Xml;

function displayXml(doc, node, indent) {
    System.print("  " * indent);
    if (node.type == Xml.ELEMENT_NODE) {
        System.print("ELEM %s" % node.name);
    } else if (node.type == Xml.TEXT_NODE) {
        System.print("TEXT %s" % node.value.trim());
    }

    var attr = node.attributes();
    for (var i = 0, len = attr.length(); i < len; ++i) {
        System.print("[%s=%s]" % attr[i].name % attr[i].value);
    }
    System.println("");

    var child = node.firstChild();
    while (child) {
        displayXml(doc, child, indent + 1);
        child = child.nextSibling();
    }
}

var doc = Xml.parseString(%{
<?xml version="1.0" encoding="UTF-8" ?>
<artists>
  <artist country="US" id="1">
    <name>BON JOVI</name>
    <price>2400</price>
    <img file="bonjovi.jpg"/>
  </artist>
  <artist country="US" id="2">
    <name>GUNS N ROSES</name>
    <price>21000</price>
    <img file="GNR.jpg"/>
  </artist>
  <artist country="DE" id="3">
    <name>Helloween</name>
    <price>2400</price>
    <img file="helloween.jpg"/>
  </artist>
</artists>
});
var root = doc.documentElement();
displayXml(doc, root);

var el = root.getElementById("3");
if (el) {
    el.remove();
}

System.println("");
System.println("getElementByTagName:");
var els = root.getElementByTagName("img");
if (els.isArray) {
    els.each(&(el) => displayXml(doc, el));
}

System.println("");
System.println("XPath:");
var nodes = doc.xpath("//car").xpath("price");
if (nodes.isArray) {
    nodes.each(&(el) => displayXml(doc, el));
}

var xmlWriter = new Xml.Writer(System);
xmlWriter.write(doc);
xmlWriter.write(root);

おわりに

だいぶ実用に近づいてきた。もうちょっとだから頑張ろう。ドキュメント書かないとね。

0
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
0
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?