swift-sion
前回予告どおり、
to type or not to type, that's the question.
前回記事より、
- Swift:swift-sion by dankogai
- Go:go-sion by mattn
- ECMAScript
(aka JavaScript):js-sion by dankogai - Rust:sion-rs by pandaman64
- Python 3:py-sion by kamimura
ここで言う
何のためにシリアライズするのか
たとえばSIONのDictionary
。js-sionでは、String:SION
の場合はObject
、Map
にデシリアライズされます。どちらもECMAScript 6には標準装備されている型です。それに対し、
一見、eval()
でなされました。今ではJSON.
という専用関数が組み込まれましたが、Array
なりObject
なり、
しかし、Bool
に相当する型が不在で、0
ならfalse
、true
という扱いです。これがPerlになると0 but true
などという場合が出てきてさらにややこしい。こうした問題をどう解決するか。
必要は発明の母
「なければ作ればいい」。これは型にも当てはまります。Perlに標準装備のJSON::PP
では、JSON::PP::Boolean
という型―Perlにおいてはクラス―を用意してこの問題を解決しています。ただし用意されているのはあくまでもJSON
を表現するのに足りないデータ型だけで、JSON
型というのは用意されていません。これはある意味当然で、
use JSON::PP;
my $array_ref = json_decode('[0,1]');
my $hash_ref = json_decode('{"one":1}')
の$array_
は普通の配列リファレンス、$hash_
は普通のハッシュJSON::PP::Boolean
はある意味必要悪であり、"" . decode_
は"1"
となります。
シリアライズする2つの理由
それでは、SION
型を用意したのでしょう。JSON同様、
理由は2つ。1つはSwiftにeval()
が存在しないこと。同様のことは不可能ではありませんが、swiftc
が必要になります。これはSwiftが根底で
もう1つは、ExpressiveBy*Literal
プロトコル……、SION
型が成立するのです。
import SION
御託はこれくらいにして、README.
どおりに環境を整えたら、
import SION
とするだけです。これだけで、
var sion:SION = [
"nil": nil,
"bool": true,
"int": -42,
"double": 42.195,
"string": "漢字、カタカナ、ひらがなの入った
string",
"array": [nil, true, 1, 1.0, "one", [1],
["one":1.0]],
"dictionary": [
"nil":nil, "bool":false, "int":0, "double":0.0, "string":"","array":[], "object":[:]
],
"url":"https://github.com/dankogai/"
]
という具合にふつうにSIONをリテラルとして受け付けます。試しに:SION
を取ってみてください。どうなりましたか?
もちろん、
SION(string:sionStr)
SION(json:jsonStr)
SION(jsonUrlString:"https://api.github.com")
SION(propertyList:plistXML.data(using:.utf8)!, format:.xml)
SION(msgPack:msgData)
デシリアライゼーションはさらに簡単で、sion.
でも"\(sion)"
でもいいですし、print(sion)
してもいいでしょう。
直感的なのは、
var sa = SION([])
で、
sa[0] = nil
sa[1] = true
sa[2] = 1
という具合にあたかも組込みの配列のように値を代入できますし、
var sd = SION([:])
sd["nil"] = nil
sd["bool"] = false
sd["int"] = 0
とできます。1点Array
では範囲外へのアクセスはfatalError
になりますし、Dictionary
で存在しないキーはnil
を返しますが、.Error()
という特別な値を用意し、
もう1点注意を要するのは、
sa[1] = true // SION.Bool(true)
sa[2] = 1 // SION.Int(1)
であり、
sa[1].bool
sa[2].int
とします。なおこれらのコンピューテッド・
sion[2].int! += 1 // now 2
sion[3].double! *= 0.5 // now 0.5
sion[4].string!.removeLast() // now "on"
sion[5].array!.append(2) // now [1, 2]
sion[6].dictionary!["two"] = 2 // now
["one":1,"two":2]
次回予告
swift-sionやSwiftyJSONのような
本誌最新号をチェック!
Software Design 2022年9月号
2022年8月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)
- 第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識 - 第2特集
「知りたい」「使いたい」「発信したい」をかなえる
OSSソースコードリーディングのススメ - 特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画]Red Hat Enterprise Linux 9最新ガイド - 短期連載
今さら聞けないSSH
[前編]リモートログインとコマンドの実行 - 短期連載
MySQLで学ぶ文字コード
[最終回]文字コードのハマりどころTips集 - 短期連載
新生「Ansible」徹底解説
[4]Playbookの実行環境(基礎編)