99 lines
No EOL
5.8 KiB
HTML
99 lines
No EOL
5.8 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<title>CLiki: cl-marshal</title>
|
|
<link rel="alternate" type="application/atom+xml" title="ATOM feed of edits to current article"
|
|
href="https://www.cliki.net/site/feed/article.atom?title=cl-marshal">
|
|
<link rel="stylesheet" href="static/css/style.css">
|
|
<link rel="stylesheet" href="static/css/colorize.css">
|
|
</head>
|
|
|
|
<body>
|
|
<span class="hidden">CLiki - cl-marshal</span>
|
|
<div id="content"><div id="content-area"><div id="article-title">cl-marshal</div><div id="article">Simple and fast marshalling of all kinds of Lisp data structures.
|
|
Convert any object into a s-expression, put it on a stream an revive it from there. Only minimal changes required to make your CLOS objects serializable. Actually you only need to add 1 method per baseclass.<p>Homepage: <a href="https://github.com/wlbr/cl-marshal">https://github.com/wlbr/cl-marshal</a><p>Dependencies: none (except asdf)<br>
|
|
License: MIT <br>
|
|
Author: <a href="Michael Wolber.html" class="internal">Michael Wolber</a><p><h2>Examples</h2><p><h4>Serialization of simple data:</h4>
|
|
<pre>
|
|
$ (ms:marshal (list 1 2 3 "Foo" "Bar" (make-array '(3) :initial-contents '(a b c))))
|
|
--> (:PCODE 1
|
|
(:LIST 1 1 2 3 (:SIMPLE-STRING 2 "Foo") (:SIMPLE-STRING 3 "Bar")
|
|
(:ARRAY 4 (3) T (A B C))))
|
|
</pre>
|
|
<h4>Deserialization:</h4>
|
|
<pre>
|
|
$ (ms:unmarshal '(:PCODE 1
|
|
(:LIST 1 1 2 3 (:SIMPLE-STRING 2 "Foo") (:SIMPLE-STRING 3 "Bar")
|
|
(:ARRAY 4 (3) T (A B C)))))
|
|
--> (1 2 3 "Foo" "Bar" #(A B C))
|
|
</pre><p>That means that a
|
|
<pre>(ms:unmarshal (ms:marshal myobject))</pre>
|
|
returns a deep clone of myobject.<p>
|
|
<h4>Objects:A more complex example</h4>
|
|
<pre>
|
|
(defclass ship ()
|
|
((name :initform "" :initarg :name :accessor name)
|
|
(dimensions :initform '(:width 0 :length 0) :initarg :dimensions :accessor dimensions)
|
|
(course :initform 0 :initarg :course :accessor course)
|
|
(cruise :initform 0 :initarg :cruise :accessor cruise) ; shall be transient
|
|
(dinghy :initform NIL :initarg :dinghy :accessor dinghy :initarg :dinghy)) ; another ship -> ref
|
|
(:documentation "A democlass. Some 'persistant slots', one transient.
|
|
Some numbers, string, lists and object references."))
|
|
|
|
|
|
(defparameter ark (make-instance 'ship :name "Ark" :course 360
|
|
:dimensions '(:width 30 :length 90)))
|
|
</pre>
|
|
Nothing happens if we try to serialize this, as one important piece is missing:
|
|
<pre>
|
|
$ (ms:marshal ark)
|
|
--> (:PCODE 1 NIL)
|
|
</pre><p>For your classes you need to add one special method: <pre>ms:class-persistant-slots</pre> There you are going to define the slots that shall be serialized, so that you can have persistant and transient slots in your class.
|
|
<pre>
|
|
(defmethod ms:class-persistant-slots ((self ship))
|
|
'(name dimensions course dinghy))
|
|
</pre>
|
|
Note that the slot cruise is not listed. Therefore it will not be serialized.<p><pre>
|
|
$ (ms:marshal ark)
|
|
--> (:PCODE 1
|
|
(:OBJECT 1 SHIP (:SIMPLE-STRING 2 "Ark") (:LIST 3 :WIDTH 30 :LENGTH 90) 360
|
|
(:LIST 4)))
|
|
</pre><p>Fine. Try a <pre>(ms:unmarshal (ms:marshal ark))</pre> and you will get a clone of the object ark.<p>The whole thing works with arrays, hashtables, lists, classes/objects, subclasses incl. multiple inheritance, all of this nested and with circular references. See <a href="https://github.com/wlbr/cl-marshal/blob/master/README.md">README.md</a> for more detailed examples.<p><a href="serialization.html" class="category">serialization</a> <a href="wire format.html" class="category">wire format</a></div></div>
|
|
<div id="footer" class="buttonbar"><ul><li><a href="cl-marshal.html">Current version</a></li>
|
|
<li><a href="https://www.cliki.net/site/history?article=cl-marshal">History</a></li>
|
|
<li><a href="https://www.cliki.net/site/backlinks?article=cl-marshal">Backlinks</a></li><li><a href="https://www.cliki.net/site/edit-article?title=cl-marshal&from-revision=3784724218">Edit</a></li><li><a href="https://www.cliki.net/site/edit-article?create=t">Create</a></li></ul></div>
|
|
</div>
|
|
<div id="header-buttons" class="buttonbar">
|
|
<ul>
|
|
<li><a href="https://www.cliki.net/">Home</a></li>
|
|
<li><a href="https://www.cliki.net/site/recent-changes">Recent Changes</a></li>
|
|
<li><a href="CLiki.html">About</a></li>
|
|
<li><a href="Text Formatting.html">Text Formatting</a></li>
|
|
<li><a href="https://www.cliki.net/site/tools">Tools</a></li>
|
|
</ul>
|
|
<div id="search">
|
|
<form action="https://www.cliki.net/site/search">
|
|
<label for="search_query" class="hidden">Search CLiki</label>
|
|
<input type="text" name="query" id="search_query" value="" />
|
|
<input type="submit" value="search" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div id="pageheader">
|
|
<div id="header">
|
|
<span id="logo">CLiki</span>
|
|
<span id="slogan">the common lisp wiki</span>
|
|
<div id="login"><form method="post" action="https://www.cliki.net/site/login">
|
|
<label for="login_name" class="hidden">Account name</label>
|
|
<input type="text" name="name" id="login_name" class="login_input" />
|
|
<label for= "login_password" class="hidden">Password</label>
|
|
<input type="password" name="password" id="login_password" class="login_input" />
|
|
<input type="submit" name="login" value="login" id="login_submit" /><br />
|
|
<div id="register"><a href="https://www.cliki.net/site/register">register</a></div>
|
|
<input type="submit" name="reset-pw" value="reset password" id="reset_pw" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body></html> |