Object serialization: Difference between revisions

Added FreeBASIC
No edit summary
(Added FreeBASIC)
 
(42 intermediate revisions by 23 users not shown)
Line 4:
=={{header|Ada}}==
This file contains the package specification containing the public definitions of the inheritance tree rooted at the type ''Message''. Each type in the inheritance tree has its own print procedure.
<langsyntaxhighlight lang="ada">with Ada.Calendar; use Ada.Calendar;
 
package Messages is
Line 28:
procedure Print(Item : Control_Message);
end Messages;</langsyntaxhighlight>
 
The next portion contains the implementation of the procedures defined in the package specification.
<langsyntaxhighlight lang="ada">with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
Line 98:
end Display;
end Messages;</langsyntaxhighlight>
 
The final section of code creates objects of the three message types and performs the printing, writing, and reading. The Ada attributes '' 'Class'Output'' serialize the object and write it to the specified stream. The '' 'Class'Input'' attributes call a function automatically provided by the compiler which reads from the specified stream file and returns the object read. The ''Display'' procedure takes an object in the inheritance tree rooted at ''Message'' and dispatches the correct print procedure.
 
<langsyntaxhighlight lang="ada">with Messages; use Messages;
with Ada.Streams.Stream_Io; use Ada.Streams.Stream_Io;
with Ada.Calendar; use Ada.Calendar;
Line 141:
end loop;
Close(The_File);
end Streams_Example;</langsyntaxhighlight>
Output results:
Time Stamp:2007-3-9
Line 165:
Serialization in ''ALGOL 68'' is achieved through a technique called
''straightening''.
<langsyntaxhighlight lang="algol68">MODE ENTITY = STRUCT([6]CHAR name, INT creation);
FORMAT entity repr = $"Name: "g", Created:"g$;
MODE PERSON = STRUCT(ENTITY entity, STRING email);
Line 193:
printf((person repr, i1, $l$));
printf((entity repr, i2, $l$))</langsyntaxhighlight>
'''flex'''ible length arrays (including '''string'''s), and tagged-'''union'''
types are problematic as the lengths of the arrays, and the ''tag'' of the
Line 210:
Name: Entity, Created: +20111111
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace Object_serialization
{
[Serializable] public class Being
{
public bool Alive { get; set; }
}
 
[Serializable] public class Animal: Being
{
public Animal() { }
 
public Animal(long id, string name, bool alive = true)
{
Id = id;
Name = name;
Alive = alive;
}
 
public long Id { get; set; }
public string Name { get; set; }
 
public void Print() { Console.WriteLine("{0}, id={1} is {2}",
Name, Id, Alive ? "alive" : "dead"); }
}
 
 
internal class Program
{
private static void Main()
{
string path =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"\\objects.dat";
 
var n = new List<Animal>
{
new Animal(1, "Fido"),
new Animal(2, "Lupo"),
new Animal(7, "Wanda"),
new Animal(3, "Kiki", alive: false)
};
 
foreach(Animal animal in n)
animal.Print();
 
using(var stream = new FileStream(path, FileMode.Create, FileAccess.Write))
new BinaryFormatter().Serialize(stream, n);
 
n.Clear();
Console.WriteLine("---------------");
List<Animal> m;
 
using(var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
m = (List<Animal>) new BinaryFormatter().Deserialize(stream);
 
foreach(Animal animal in m)
animal.Print();
}
}
}</syntaxhighlight>
<pre>Fido, id=1 is alive
Lupo, id=2 is alive
Wanda, id=7 is alive
Kiki, id=3 is dead
---------------
Fido, id=1 is alive
Lupo, id=2 is alive
Wanda, id=7 is alive
Kiki, id=3 is dead</pre>
 
=={{header|C++}}==
compiled with g++ -lboost_serialization serializationtest3.cpp -o serializationtest3
 
<langsyntaxhighlight lang="cpp">#include <string>
#include <fstream>
#include <boost/serialization/string.hpp>
Line 331 ⟶ 406:
w2.print( ) ;
return 0 ;
}</langsyntaxhighlight>
creating the following output:
<pre>
Line 347 ⟶ 422:
wage per hour: 55.35
</pre>
=={{header|C sharp|C#}}==
<lang csharp>using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace Object_serialization
{
[Serializable] public class Being
{
public bool Alive { get; set; }
}
 
[Serializable] public class Animal: Being
{
public Animal() { }
 
public Animal(long id, string name, bool alive = true)
{
Id = id;
Name = name;
Alive = alive;
}
 
public long Id { get; set; }
public string Name { get; set; }
 
public void Print() { Console.WriteLine("{0}, id={1} is {2}",
Name, Id, Alive ? "alive" : "dead"); }
}
 
 
internal class Program
{
private static void Main()
{
string path =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"\\objects.dat";
 
var n = new List<Animal>
{
new Animal(1, "Fido"),
new Animal(2, "Lupo"),
new Animal(7, "Wanda"),
new Animal(3, "Kiki", alive: false)
};
 
foreach(Animal animal in n)
animal.Print();
 
using(var stream = new FileStream(path, FileMode.Create, FileAccess.Write))
new BinaryFormatter().Serialize(stream, n);
 
n.Clear();
Console.WriteLine("---------------");
List<Animal> m;
 
using(var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
m = (List<Animal>) new BinaryFormatter().Deserialize(stream);
 
foreach(Animal animal in m)
animal.Print();
}
}
}</lang>
<pre>Fido, id=1 is alive
Lupo, id=2 is alive
Wanda, id=7 is alive
Kiki, id=3 is dead
---------------
Fido, id=1 is alive
Lupo, id=2 is alive
Wanda, id=7 is alive
Kiki, id=3 is dead</pre>
 
=={{header|Caché ObjectScript}}==
 
<langsyntaxhighlight lang="cos">Class Serialize.Employee Extends %SerialObject
{
 
Line 449 ⟶ 450:
Property Department As %String [ Private ];
 
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="cos">Class Serialize.Worker Extends Employee
{
 
Line 475 ⟶ 476:
Property HourlyPay As %Numeric [ Private ];
 
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="cos">Class Serialize.Example Extends %SerialObject
{
 
Line 535 ⟶ 536:
Property Workers As list Of Worker;
 
}</langsyntaxhighlight>
 
{{out|Examples}}
Line 560 ⟶ 561:
{{libheader|cl-serializer}}
 
<langsyntaxhighlight lang="lisp">(defmacro with-serialization-to-file ((stream pathname) &body body)
`(with-open-file (,stream ,pathname
:element-type '(unsigned-byte 8)
Line 571 ⟶ 572:
 
(defclass person (entity)
((name :initarg :name :initform "The Nameless One")))</langsyntaxhighlight>
 
And now the REPL log:
 
<langsyntaxhighlight lang="lisp">CL-USER> (list (make-instance 'entity)
(make-instance 'person))
 
Line 609 ⟶ 610:
Slots with :INSTANCE allocation:
NAME = "The Nameless One"
(#<ENTITY {1003C12911}> #<PERSON {1003C12A81}>)</langsyntaxhighlight>
 
=={{header|D}}==
Line 627 ⟶ 628:
Run "pbcompiler test.proto" to generate the serializable code. It should generate a D code file named test.d.
In your main file, use the following code:
<langsyntaxhighlight lang="d">import test1;
import std.stdio;
import std.file;
Line 661 ⟶ 662:
writefln("Output data:");
base.print;
}</langsyntaxhighlight>
 
=={{header|E}}==
Line 667 ⟶ 668:
(Inheritance, while supported by various features and patterns, is not a preferred design component in [[E]]; nor are simple record data structures.)
 
<langsyntaxhighlight lang="e">def makeEvent(time :int) {
return def event {
to __printOn(out) { out.print(`@@$time`) }
Line 687 ⟶ 688:
to getPosition() { return position }
}
}</langsyntaxhighlight>
 
After defining our data types, we can prepare to serialize them.
 
<langsyntaxhighlight lang="e">def surgeon := <import:org.erights.e.elib.serial.makeSurgeon>().diverge()
surgeon.addExit(makeEvent, "makeEvent")
surgeon.addExit(makeArrival, "makeArrival")</langsyntaxhighlight>
 
The 'exits' of the surgeon (so called because it cuts and joins object subgraphs) specify the points at which serialization should stop, instead replacing references to the objects with the specified names. On unserialization, the names are looked up and replaced with the corresponding objects. (The surgeon provides default exits for such things as <tt>false</tt>, <tt>true</tt>, <tt>null</tt>, and the list constructor.)
<langsyntaxhighlight lang="e">def objs := [makeEvent(timer.now()),
makeArrival(timer.now(), "Smith", 7)]
 
stdout.println(objs)
<file:objects.dat>.setBytes(surgeon.serialize(objs))
stdout.println(surgeon.unserialize(<file:objects.dat>.getBytes()))</langsyntaxhighlight>
 
=={{header|EchoLisp}}==
Our classes will be 'struct' objects, with custom #:tostring procedures, as required. The instances are saved/restored to/from local storage. Serialization is performed by JSONifying the objects. References between instances of struct's are kept in the process. Auto-references and circular references are correctly maintained since EchoLisp version 2.11.
<syntaxhighlight lang="lisp">
(define (person->string self) (format "%a : person." (person-name self)))
(define (writer->string self) (format "%a: writer of %a."
(person-name self)
(writer-books self)))
(define (father->string self) (format "%a: father of %a."
(person-name self)
(map person-name (father-children self))))
; 'classes' definition, with inheritance.
; a writer is a person, too.
(struct person (name) #:tostring person->string)
(struct writer person (books) #:tostring writer->string)
(struct father person (children) #:tostring father->string)
 
(define simon (writer "Simon" '(my-life my-wife my-bike)))
(define elvis (person "Elvis"))
(define papa (father "papa" (list simon elvis)))
 
(local-put-value 'simon simon "objects.dat")
📕 local-db: local-put:unknown store : "objects.dat"
;; forgot to create the store. Create it :
(local-make-store "objects.dat") → "objects.dat"
 
(local-put-value 'simon simon "objects.dat")
(local-put-value 'elvis elvis "objects.dat")
(local-put-value 'papa papa "objects.dat")
 
;; inspect
simon → Simon: writer of (my-life my-wife my-bike).
papa → papa: father of (Simon Elvis).
elvis → Elvis : person.
</syntaxhighlight>
{{output}}
<syntaxhighlight lang="lisp">
;; reboot (close the browser window)
; inspect objects.dat :
(local-keys 'objects.dat) → ("elvis" "papa" "simon")
 
(define simon (local-get-value 'simon "objects.dat"))
(define elvis (local-get-value 'elvis "objects.dat"))
(define papa (local-get-value 'papa "objects.dat"))
 
; data are restored
simon → Simon: writer of (my-life my-wife my-bike).
papa → papa: father of (Simon Elvis).
 
;; check if references (pointers) are restored
(set-writer-name! simon "Antoinette") → "Antoinette"
simon→ Antoinette: writer of (my-life my-wife my-bike).
 
;; inspect
papa → papa: father of (Antoinette Elvis). ; YES 😳 !
 
;; - Self-referencing (EchoLisp version 2.11)
;; add 'papa' to the chidren of 'papa' - whatever this means - and print it :
(set-father-children! papa (list simon papa elvis))
papa → papa: father of (Antoinette papa Elvis).
 
; save/restore
(local-put-value 'papa papa "objects.dat")
(define papa (local-get-value 'papa "objects.dat"))
papa → papa: father of (Antoinette papa Elvis).
</syntaxhighlight>
 
=={{header|Erlang}}==
Erlang is not object oriented. This code is based upon my understanding of the Algol 68 example above.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( object_serialization ).
 
Line 734 ⟶ 803:
print( Entity ),
io:fwrite( "\temail: ~p~n", [Email] ).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 746 ⟶ 815:
Entity: name: "Entity", date: 20111111
</pre>
 
=={{header|Factor}}==
The <code>serialize</code> vocabulary provides words for serializing and deserializing any Factor object other than continuations. This example demonstrates that objects may be serialized individually, one at a time. In practice, it's probably easier to serialize a collection of objects.
<syntaxhighlight lang="factor">USING: accessors combinators.extras io io.encodings.binary
io.files io.files.info kernel prettyprint serialize ;
IN: rosetta-code.object-serialization
 
! Define two classes, item and armor. armor is a subclass of
! item.
 
TUPLE: item name value ;
TUPLE: armor < item physical-resistance fire-resistance ;
 
! Define boa constructors for both classes using C: shorthand.
! boa means By Order of Arguments, and yes, this is a pun on boa
! constrictors.
 
C: <item> item
C: <armor> armor
 
! Create three example items and print them out
! non-destructively.
 
"Fish scales" 0.05 <item>
"Gold piece" 1 <item>
"Breastplate of Ashannar" 50,000 55 30 <armor>
[ [ . ] keep ] tri@ nl
 
! Serialize the three objects to a binary file named
! objects.dat.
 
"Serializing objects to objects.dat . . . " print
"objects.dat" binary [ [ serialize ] tri@ ] with-file-writer
 
! Check that objects.dat exists.
 
"objects.dat exists? " write "objects.dat" exists? .
"Size on disk: " write "objects.dat" file-info size>> pprint
" bytes" print nl
 
! Deserialize three objects from objects.dat.
 
"Deserializing objects from objects.dat . . . " print nl
"objects.dat" binary [ [ deserialize ] thrice ] with-file-reader
 
! Print out deserialized objects.
 
[ . ] tri@</syntaxhighlight>
{{out}}
<pre>
T{ item { name "Fish scales" } { value 0.05 } }
T{ item { name "Gold piece" } { value 1 } }
T{ armor
{ name "Breastplate of Ashannar" }
{ value 50000 }
{ physical-resistance 55 }
{ fire-resistance 30 }
}
 
Serializing objects to objects.dat . . .
objects.dat exists? t
Size on disk: 206 bytes
 
Deserializing objects from objects.dat . . .
 
T{ item { name "Fish scales" } { value 0.05 } }
T{ item { name "Gold piece" } { value 1 } }
T{ armor
{ name "Breastplate of Ashannar" }
{ value 50000 }
{ physical-resistance 55 }
{ fire-resistance 30 }
}
</pre>
 
=={{header|FreeBASIC}}==
FreeBASIC does not support object-oriented programming such as classes and inheritance directly. However, we can simulate some aspects of object-oriented programming using procedures and user-defined types (UDTs).
 
For serialization, FreeBASIC does not have built-in support for this. We need to manually write and read each field of your UDTs to and from a file.
<syntaxhighlight lang="vbnet">Type Person
nombre As String
edad As Integer
End Type
 
Sub PrintPerson(p As Person)
Print "Name: "; p.nombre
Print "Age: "; p.edad
End Sub
 
Sub Serialize(p As Person, filename As String)
Open filename For Binary As #1
Put #1, , p.nombre
Put #1, , p.edad
Close #1
End Sub
 
Sub Deserialize(p As Person, filename As String)
Open filename For Binary As #1
Get #1, , p.nombre
Get #1, , p.edad
Close #1
End Sub
 
Dim pp As Person
pp.nombre = "Juan Hdez."
pp.edad = 52
 
Serialize(pp, "objects.dat")
Deserialize(pp, "objects.dat")
 
PrintPerson(pp)
 
Sleep</syntaxhighlight>
{{out}}
<pre>Name: Juan Hdez.
Age: 52</pre>
 
=={{header|Go}}==
Line 751 ⟶ 936:
 
A note on object oriented stuff, the object hierarchy required by the task description is implemented here with embedded structs. The polymorphism required by the task description is handled nicely with an interface. The functional polymorphism is orthogonal to the object hierarchy, not conflated with it.
<langsyntaxhighlight lang="go">package main
 
import (
Line 904 ⟶ 1,089:
fmt.Println(" collie, not trained, doesn't catch frisbee")
}
}</langsyntaxhighlight>
Output:
<pre>created:
Line 920 ⟶ 1,105:
=={{header|Groovy}}==
Sample Serializable Classes (borrowed from Java example. Sorta.):
<langsyntaxhighlight lang="groovy">class Entity implements Serializable {
static final serialVersionUID = 3504465751164822571L
String name = 'Thingamabob'
Line 930 ⟶ 1,115:
Person() { name = 'Clement' }
Person(name) { this.name = name }
}</langsyntaxhighlight>
 
Writing objects:
<langsyntaxhighlight lang="groovy">File objectStore = new File('objectStore.ser')
if (objectStore.exists()) { objectStore.delete() }
assert ! objectStore.exists()
Line 951 ⟶ 1,136:
os << new Person('Schroeder')
} catch (e) { throw new Exception(e) } finally { os?.close() }
assert objectStore.exists()</langsyntaxhighlight>
 
Reading objects:
<langsyntaxhighlight lang="groovy">def is
try {
is = objectStore.newObjectInputStream(this.class.classLoader)
Line 961 ⟶ 1,146:
 
objectStore.delete()
assert ! objectStore.exists()</langsyntaxhighlight>
 
Output:
Line 975 ⟶ 1,160:
[lists, are, serializable]
Schroeder</pre>
 
=={{header|Haskell}}==
 
Example uses [https://hackage.haskell.org/package/binary <tt>binary</tt>] package. Since Haskell doesn't directly support OO-style inheritance, we use a sum type instead:
 
<syntaxhighlight lang="haskell">{-# LANGUAGE DeriveGeneric #-}
 
module Main (main) where
 
import qualified Data.ByteString.Lazy as ByteString (readFile, writeFile)
import Data.Binary (Binary)
import qualified Data.Binary as Binary (decode, encode)
import GHC.Generics (Generic)
 
data Employee =
Manager String String
| IndividualContributor String String
deriving (Generic, Show)
instance Binary Employee
 
main :: IO ()
main = do
ByteString.writeFile "objects.dat" $ Binary.encode
[ IndividualContributor "John Doe" "Sales"
, Manager "Jane Doe" "Engineering"
]
 
bytes <- ByteString.readFile "objects.dat"
let employees = Binary.decode bytes
print (employees :: [Employee])</syntaxhighlight>
 
=={{Header|Insitux}}==
 
Insitux does not have OOP-style objects, nor a recommended way to serialise into binary. The recommended serialisation/deserialisation method ([https://www.rosettacode.org/wiki/JSON#Insitux as JSON is not fully capable]) is <code>str</code> to serialise into a string, and <code>safe-eval</code> to deserialise from string. If <code>eval</code> was used it would be vulnerable to arbitrary code execution.
 
 
<syntaxhighlight lang="insitux">
(var object {:a 1 :b "Hello, world!" [1 2 3] :c}
serialised (str object)
deserialised (safe-eval serialised))
 
(print "Object: " object)
(print "Serialised: " serialised)
(str "Deserialised: " deserialised)
</syntaxhighlight>
 
{{out}}
 
<pre>
Object: {:a 1, :b "Hello, world!", [1 2 3] :c}
Serialised: {:a 1, :b "Hello, world!", [1 2 3] :c}
Deserialised: {:a 1, :b "Hello, world!", [1 2 3] :c}
</pre>
 
=={{header|J}}==
Line 980 ⟶ 1,218:
This should be sufficient for this task:
 
<langsyntaxhighlight lang="j">lin_z_=:5!:5
serializeObject=:3 :0
p=. copath y
Line 1,020 ⟶ 1,258:
print__r1''
print__k1''
print__s1''</langsyntaxhighlight>
 
Here is how the last part looks in action:
 
<langsyntaxhighlight lang="j"> print__R''
room size small
print__K''
Line 1,040 ⟶ 1,278:
kitchen size medium
print__s1''
kitchen with sink size large</langsyntaxhighlight>
 
Note also that J does not attempt to distinguish, at the language level, between an object reference and something that looks like an object reference but is not. This must be done at the application level, which in turn can create a variety of opportunities and/or burdens for the program designer.
 
(And this is more than adequate for the use case J's object system was designed for, which is to provide a mechanism where independent programmers can work on different modules of a program with well defined interfaces. Of course, if you try to make it complicated, or try to design something with incomprehensible interfaces, that will create problems.)
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.io.*;
 
// classes must implement java.io.Serializable in order to be serializable
Line 1,104 ⟶ 1,344:
}
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
abstract type Hello end
 
struct HelloWorld <: Hello
name::String
HelloWorld(s) = new(s)
end
 
struct HelloTime <: Hello
name::String
tnew::DateTime
HelloTime(s) = new(s, now())
end
 
sayhello(hlo) = println("Hello to this world, $(hlo.name)!")
 
sayhello(hlo::HelloTime) = println("It is now $(now()). Hello from back in $(hlo.tnew), $(hlo.name)!")
 
h1 = HelloWorld("world")
h2 = HelloTime("new world")
 
sayhello(h1)
sayhello(h2)
 
fh = open("objects.dat", "w")
serialize(fh, h1)
serialize(fh,h2)
close(fh)
 
sleep(10)
 
fh = open("objects.dat", "r")
hh1 = deserialize(fh)
hh2 = deserialize(fh)
close(fh)
 
sayhello(hh1)
sayhello(hh2)
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.2.0
 
import java.io.*
 
open class Entity(val name: String = "Entity"): Serializable {
override fun toString() = name
 
companion object {
val serialVersionUID = 3504465751164822571L
}
}
 
class Person(name: String = "Brian"): Entity(name), Serializable {
companion object {
val serialVersionUID = -9170445713373959735L
}
}
 
fun main(args: Array<String>) {
val instance1 = Person()
println(instance1)
 
val instance2 = Entity()
println(instance2)
 
// serialize
try {
val out = ObjectOutputStream(FileOutputStream("objects.dat"))
out.writeObject(instance1)
out.writeObject(instance2)
out.close()
println("Serialized...")
}
catch (e: IOException) {
println("Error occurred whilst serializing")
System.exit(1)
}
 
// deserialize
try {
val inp = ObjectInputStream(FileInputStream("objects.dat"))
val readObject1 = inp.readObject()
val readObject2 = inp.readObject()
inp.close()
println("Deserialized...")
println(readObject1)
println(readObject2)
}
catch (e: IOException) {
println("Error occurred whilst deserializing")
System.exit(1)
}
catch (e: ClassNotFoundException) {
println("Unknown class for deserialized object")
System.exit(1)
}
}</syntaxhighlight>
 
{{out}}
<pre>
Brian
Entity
Serialized...
Deserialized...
Brian
Entity
</pre>
 
=={{header|Neko}}==
<syntaxhighlight lang="actionscript">/* Object serialization, in Neko */
 
var file_open = $loader.loadprim("std@file_open", 2)
var file_write = $loader.loadprim("std@file_write", 4)
var file_read = $loader.loadprim("std@file_read", 4)
var file_close = $loader.loadprim("std@file_close", 1)
 
var serialize = $loader.loadprim("std@serialize", 1)
var unserialize = $loader.loadprim("std@unserialize", 2)
 
/* Inheritance by prototype */
proto = $new(null)
proto.print = function () { $print(this, "\n") }
 
obj = $new(null)
obj.msg = "Hello"
obj.dest = $array("Town", "Country", "World")
 
$objsetproto(obj, proto)
$print("Original:\n")
obj.print()
 
/* Serialize the object */
var thing = serialize(obj)
var len = $ssize(thing)
 
/* To disk */
var f = file_open("object-serialization.bin", "w")
file_write(f, thing, 0, len)
file_close(f)
 
/* Load the binary data into a new string space */
f = file_open("object-serialization.bin", "r")
var buff = $smake(len)
file_read(f, buff, 0, len)
file_close(f)
 
/* Unserialize the object into a new variable */
var other = unserialize(buff, $loader)
$print("deserialized:\n")
other.print()</syntaxhighlight>
 
{{out}}
<pre>prompt$ nekoc object-serialization.neko
prompt$ neko object-serialization
Original:
{ dest => [Town,Country,World], msg => Hello }
deserialized:
{ dest => [Town,Country,World], msg => Hello }
prompt$ xxd object-serialization.bin
00000000: 6f62 5e66 c261 0300 0000 7304 0000 0054 ob^f.a....s....T
00000010: 6f77 6e73 0700 0000 436f 756e 7472 7973 owns....Countrys
00000020: 0500 0000 576f 726c 6441 1a53 0073 0500 ....WorldA.S.s..
00000030: 0000 4865 6c6c 6f00 0000 0070 6f2d 588b ..Hello....po-X.
00000040: c84c 7314 0000 006f 626a 6563 742d 7365 .Ls....object-se
00000050: 7269 616c 697a 6174 696f 6e02 0000 0000 rialization.....
00000060: 0000 0061 0000 0000 0000 0000 7a ...a........z</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import marshal, streams
type
Base = object of RootObj
name: string
Descendant = object of Base
proc newBase(): Base = Base(name: "base")
proc newDescendant(): Descendant = Descendant(name: "descend")
proc print(obj: Base) =
echo(obj.name)
 
var
base = newBase()
descendant = newDescendant()
print(base)
print(descendant)
 
var strm = newFileStream("objects.dat", fmWrite)
store(strm, (base, descendant))
strm.close()
 
var t: (Base, Descendant)
load(newFileStream("objects.dat", fmRead), t)
print(t[0])
print(t[1])
</syntaxhighlight>
{{out}}
<pre>
base
descend
base
descend
</pre>
 
=={{header|Objeck}}==
<syntaxhighlight lang="objeck">
bundle Default {
class Thingy {
@id : Int;
 
New(id : Int) {
@id := id;
}
 
method : public : Print() ~ Nil {
@id->PrintLine();
}
}
 
class Person from Thingy {
@name : String;
 
New(id : Int, name : String) {
Parent(id);
@name := name;
}
 
method : public : Print() ~ Nil {
@id->PrintLine();
@name->PrintLine();
}
}
 
class Serial {
function : Main(args : String[]) ~ Nil {
t := Thingy->New(7);
p := Person->New(13, "Bush");
 
s := IO.Serializer->New();
s->Write(t->As(Base));
s->Write(p->As(Base));
 
writer := IO.FileWriter->New("objects.dat");
writer->WriteBuffer(s->Serialize());
writer->Close();
 
buffer := IO.FileReader->ReadBinaryFile("objects.dat");
d := IO.Deserializer->New(buffer);
 
t2 := d->ReadObject()->As(Thingy);
t2->Print();
p2 := d->ReadObject()->As(Person);
p2->Print();
}
}
}
</syntaxhighlight>
 
=={{header|Objective-C}}==
Line 1,116 ⟶ 1,615:
There exists also a way of serializing without the GNUstep/Cocoa framework, using the runtime of Objective-C (so it could be slightly implementation dependent, see [[wp:Serialization#Objective-C|Serialization on Wikipedia]]). (I will work on it and will put here a full working example compatible with the task).
 
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
// a fantasy two level hierarchy
Line 1,124 ⟶ 1,623:
int numberOfLegs;
}
- (idinstancetype) initWithName: (NSString*)name andLegs: (NSInteger)legs;
- (void) dump;
// the following allows "(de)archiving" of the object
- (void) encodeWithCoder: (NSCoder*)coder;
- (id) initWithCoder: (NSCoder*)coder;
@end
 
@implementation Animal
- (idinstancetype) initWithName: (NSString*)name andLegs: (NSInteger)legs
{
if ((self = [super init])) {
animalName = [name retain];
numberOfLegs = legs;
}
return self;
}
- (void) dealloc
{
[animalName release];
[super dealloc];
}
- (void) dump
Line 1,155 ⟶ 1,646:
[coder encodeInt: numberOfLegs forKey: @"Animal.legs"];
}
- (idinstancetype) initWithCoder: (NSCoder*)coder
{
if ((self = [super init])) {
animalName = [[coder decodeObjectForKey: @"Animal.name"] retain];
numberOfLegs = [coder decodeIntForKey: @"Animal.legs"];
}
Line 1,170 ⟶ 1,661:
NSMutableArray *eatenList;
}
- (idinstancetype) initWithName: (NSString*)name hasFur: (BOOL)fur;
- (void) addEatenThing: (NSString*)thing;
- (void) dump;
// for archiving / dearchiving:
- (void) encodeWithCoder: (NSCoder*)coder;
- (id) initWithCoder: (NSCoder*)coder;
@end
 
@implementation Mammal
- (idinstancetype) init
{
if ((self = [super init])) {
Line 1,187 ⟶ 1,674:
return self;
}
- (idinstancetype) initWithName: (NSString*)name hasFur: (BOOL)fur
{
if ((self = [super initWithName: name andLegs: 4])) {
Line 1,198 ⟶ 1,685:
{
[eatenList addObject: thing];
}
- (void) dealloc
{
[eatenList release];
[super dealloc];
}
- (void) dump
Line 1,208 ⟶ 1,690:
[super dump];
NSLog(@"has fur? %@", (hasFur) ? @"yes" : @"no" );
// fast enum not implemented yet in gcc 4.3, at least
// without a patch that it seems to exist...
NSEnumerator *en = [eatenList objectEnumerator];
id element;
NSLog(@"it has eaten %d things:", [eatenList count]);
for ( id element in eatenList )
while( (element = [en nextObject]) != nil )
NSLog(@"it has eaten a %@", element);
NSLog(@"end of eaten things list");
Line 1,224 ⟶ 1,702:
[coder encodeObject: eatenList forKey: @"Mammal.eaten"];
}
- (idinstancetype) initWithCoder: (NSCoder*)coder
{
if ((self = [super initWithCoder: coder])) {
hasFur = [coder decodeBoolForKey: @"Mammal.hasFur"];
eatenList = [[coder decodeObjectForKey: @"Mammal.eaten"] retain];
}
return self;
Line 1,237 ⟶ 1,715:
int main()
{
@autoreleasepool {
Mammal *aMammal;
Animal *anAnimal;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// let us create a fantasy animal
Animal *anAnimal = [[Animal alloc]
initWithName: @"Eptohippos"
andLegs: 7
];
// for some reason an Eptohippos is not an horse with 7 legs,
// and it is not a mammal, of course...
 
// let us create a fantasy mammal (which is an animal too)
Mammal *aMammal = [[Mammal alloc]
initWithName: @"Mammaluc"
hasFur: YES
];
// let us add some eaten stuff...
[aMammal addEatenThing: @"lamb"];
[aMammal addEatenThing: @"table"];
[aMammal addEatenThing: @"web page"];
 
// dump anAnimal
NSLog(@"----- original Animal -----");
[anAnimal dump];
 
// dump aMammal...
NSLog(@"----- original Mammal -----");
[aMammal dump];
 
// now let us store the objects...
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *arch = [[NSKeyedArchiver alloc]
initForWritingWithMutableData: data];
[arch encodeObject: anAnimal forKey: @"Eptohippos"];
[arch encodeObject: aMammal forKey: @"Mammaluc"];
[arch finishEncoding];
[anAnimal release];
[data writeToFile: @"objects.dat" atomically: YES];
[aMammal release];
[arch finishEncoding];
[arch release];
[data writeToFile: @"objects.dat" atomically: YES];
[data release];
 
// now we want to retrieve the saved objects...
NSData *ldata = [[NSData alloc]
initWithContentsOfFile: @"objects.dat"];
NSKeyedUnarchived *darch = [[NSKeyedUnarchiver alloc]
initForReadingWithData: ldata];
Animal *archivedAnimal = [darch decodeObjectForKey: @"Eptohippos"];
Mammal *archivedMammal = [darch decodeObjectForKey: @"Mammaluc"];
[darch finishDecoding];
[ldata release];
[darch release];
 
// now let's dump/print the objects...
NSLog(@"\n");
NSLog(@"----- the archived Animal -----");
[archivedAnimal dump];
NSLog(@"----- the archived Mammal -----");
[archivedMammal dump];
 
}
[pool release];
return EXIT_SUCCESS;
}</langsyntaxhighlight>
 
=={{header|Objeck}}==
<lang objeck>
bundle Default {
class Thingy {
@id : Int;
 
New(id : Int) {
@id := id;
}
 
method : public : Print() ~ Nil {
@id->PrintLine();
}
}
 
class Person from Thingy {
@name : String;
 
New(id : Int, name : String) {
Parent(id);
@name := name;
}
 
method : public : Print() ~ Nil {
@id->PrintLine();
@name->PrintLine();
}
}
 
class Serial {
function : Main(args : String[]) ~ Nil {
t := Thingy->New(7);
p := Person->New(13, "Bush");
 
s := IO.Serializer->New();
s->Write(t->As(Base));
s->Write(p->As(Base));
 
writer := IO.FileWriter->New("objects.dat");
writer->WriteBuffer(s->Serialize());
writer->Close();
 
buffer := IO.FileReader->ReadBinaryFile("objects.dat");
d := IO.Deserializer->New(buffer);
 
t2 := d->ReadObject()->As(Thingy);
t2->Print();
p2 := d->ReadObject()->As(Person);
p2->Print();
}
}
}
</lang>
 
=={{header|OCaml}}==
Line 1,360 ⟶ 1,776:
Objects which contain methods are difficult to serialize because it will want to serialize those methods too, but functions usually cannot be serialized. Instead, here we perform the task on non-object datatypes, with an outside function to print them.
 
<langsyntaxhighlight lang="ocaml">type entity = { name : string }
 
let create_entity () = { name = "Entity" }
Line 1,382 ⟶ 1,798:
 
print_entity result1;;
print_entity result2;;</langsyntaxhighlight>
 
The module which provides functions to encode arbitrary data structures as sequences of bytes is [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html the module Marshal].
 
=={{header|Ol}}==
All objects (values and references) can be serialized using `fasl-save` (by `fasl-encode`) and deserialized using `fasl-load` (by `fasl-decode`).
 
<syntaxhighlight lang="scheme">
$ ol
Welcome to Otus Lisp 1.2,
type ',help' to help, ',quit' to end session.
> (define Object (tuple
'(1 2 3 4) ; list
#(4 3 2 1) ; bytevector
"hello" ; ansi string
"こんにちは" ; unicode string
(list->ff '(; associative array
(1 . 123456)
(2 . second)
(3 . "-th-")))
{(4 . 'sym) ; alternatively declared..
(5 . +)} ; ..associative array
#false ; value
-123 ; short number
123456789012345678901234567890123456789 ; long number
)
;; Defined Object
#((1 2 3 4) #(4 3 2 1) hello こんにちは #ff((1 . 123456) (2 . second) (3 . -th-))
#ff((4 . sym) (5 . #<function>)) #false -123
123456789012345678901234567890123456789)
 
> (fasl-save Object "/tmp/object.bin")
#true
 
> (define New (fasl-load "/tmp/object.bin" #false))
;; Defined New
#((1 2 3 4) #(4 3 2 1) hello こんにちは #ff((1 . 123456) (2 . second) (3 . -th-))
#ff((4 . sym) (5 . #<function>)) #false -123
123456789012345678901234567890123456789)
 
> (equal? Object New)
#true
 
> ,quit
bye-bye :/
$
</syntaxhighlight>
 
=={{header|Oz}}==
Stateless values can easily be serialized with functions from the [httphttps://wwwmozart.github.io/mozart-oz.org/homev1/doc-1.4.0/system/node57.html Pickle] module. Objects are not stateless, though.
 
Some objects can be converted to a stateless chunk by using [httphttps://wwwmozart.github.io/mozart-oz.org/homev1/doc-1.4.0/system/node96.html#section.objectsupport.reflect ObjectSupport.reflect]. For technical reasons, this will only work for a small subset of classes.
 
For a general solution, see [[Object Serialization/Oz]].
Line 1,393 ⟶ 1,855:
=={{header|Perl}}==
{{libheader|Storable}}
<langsyntaxhighlight lang="perl">{
package Greeting;
sub new {
Line 1,427 ⟶ 1,889:
print $g2->stringify;
print $s2->stringify;
};</langsyntaxhighlight>
 
{{libheader|MooseX}}
 
The same, using [[MooseX]] to serialize to [[uses format::JSON]].
<langsyntaxhighlight lang="perl">use MooseX::Declare;
 
class Greeting {
Line 1,457 ⟶ 1,919:
print $g2->string;
print $s2->string;
</syntaxhighlight>
</lang>
This time the objects were serialized to the [http://www.json.org/ JSON] format. Other supported formats are [http://search.cpan.org/perldoc?Storable Storable] and [http://www.yaml.org/ YAML].
 
=={{header|Phix}}==
The serialize() and deserialize() functions handle any kind of data. Whether they are binary, text, data types, classes,
or whatever you choose to treat as such, is up to you.
 
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">include</span> <span style="color: #008000;">"builtins/serialize.e"</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">randobj</span><span style="color: #0000FF;">()</span>
<span style="color: #000080;font-style:italic;">-- test function (generate some random garbage)</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)<=</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- make sequence[1..3]</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">randobj</span><span style="color: #0000FF;">())</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)<=</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- make string</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span> <span style="color: #000080;font-style:italic;">-- half int/half float</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">o1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">randobj</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">o2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">randobj</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">o3</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">randobj</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">({</span><span style="color: #000000;">o1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">o2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">o3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fh</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"objects.dat"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"wb"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">serialize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o1</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">serialize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o2</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">serialize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o3</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"==="</span>
<span style="color: #000000;">fh</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"objects.dat"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"rb"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">deserialize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">deserialize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">deserialize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fh</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">delete_file</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"objects.dat"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
 
{{out}}
<pre>
{1.5,
{"JJJJJJJJ", "FFFF", {4}},
{{{0.5}, 3}, 3,1}}
"==="
1.5
{"JJJJJJJJ","FFFF",{4}}
{{{0.5},3},3,1}
</pre>
 
=={{header|PHP}}==
Serialization in PHP is straightforward. The built-in function [http://www.php.net/manual/en/function.serialize.php serialize()] handles it in a single statement.
<langsyntaxhighlight lang="php">$myObj = new Object();
$serializedObj = serialize($myObj);</langsyntaxhighlight>
In order to un-serialize the object, use the [http://www.php.net/manual/en/function.unserialize.php unserialize()] function. Note that the class of object must be defined in the script where un-serialization takes place, or the class' methods will be lost.
 
Line 1,471 ⟶ 1,988:
back. This functionality is also used internally for database access and
interprocess-communication.
<langsyntaxhighlight PicoLisplang="picolisp">(class +Point)
# x y
 
Line 1,500 ⟶ 2,017:
(out "objects.dat"
(pr (val P) (getl P))
(pr (val C) (getl C)) )</langsyntaxhighlight>
<langsyntaxhighlight PicoLisplang="picolisp">(in "objects.dat"
(putl (setq A (box (rd))) (rd))
(putl (setq B (box (rd))) (rd)) )
 
(print> A)
(print> B)</langsyntaxhighlight>
Output:
<pre>Point 3,4
Line 1,514 ⟶ 2,031:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python"># Object Serialization in Python
# serialization in python is accomplished via the Pickle module.
# Alternatively, one can use the cPickle module if speed is the key,
Line 1,550 ⟶ 2,067:
 
i1.printName()
i2.printName()</langsyntaxhighlight>
 
=={{header|Racket}}==
 
Serialization is described in the Racket documentation in: [http://docs.racket-lang.org/reference/serialization.html?q=serialize Serialization], and more specifically with respect to object oriented programming classes: [http://docs.racket-lang.org/reference/objectserialize.html?q=serializable-class#%28form._%28%28lib._racket%2Fprivate%2Fclass-internal..rkt%29._define-serializable-class%29%29 Object Serialization].
 
The serialization needs to be included with
<syntaxhighlight lang="racket">(require racket/serialize)</syntaxhighlight>
The rest is covered by the Racket language.
 
(I have elided the paths in objects.dat -- you wouldn't be able to use them anyway)
 
<syntaxhighlight lang="racket">#lang racket
;; Object Serialization: Tim Brown, Oct. 2014
(require racket/serialize)
 
(define (join-person-name-list persons)
(string-join (map (λ (c) (send c ->string)) persons) ", "))
 
(define-serializable-class person% object%
(init-field name [siblings null])
(define/public (->string #:show (show null))
(cond
[(and (member 'siblings show) (not (null? siblings)))
(format "~a (~a)" name (join-person-name-list siblings))]
[else name]))
(super-new))
 
(define-serializable-class parent% person%
(init-field [children null])
(define/override (->string #:show (show null))
(cond
[(and (member 'children show) (not (null? children)))
(format "~a [~a]" (super ->string #:show show) (join-person-name-list children))]
[else (super ->string #:show show)]))
(super-new))
 
;; horribly out of fashion and probaly no longer PC
(define-serializable-class nuclear-family% object%
(init-field father mother children)
(define/public (->string)
(string-append
(format "~a + ~a -> " (send father ->string) (send mother ->string))
(format "~a" (join-person-name-list children))))
(super-new))
 
;; =| TESTS |=========================================================================================
(define jack (new person% [name "Jack"]))
(define joan (new person% [name "Joan"]))
(set-field! siblings jack (list joan))
(set-field! siblings joan (list jack))
(define the-kids (list jack joan))
(define john (new parent% [name "John"] [children the-kids]))
(define jane (new parent% [name "Jane"] [children the-kids]))
 
(define the-family
(new nuclear-family% [father john] [mother jane] [children the-kids]))
 
(define (duplicate-object-through-file o f-name)
(with-output-to-file f-name #:exists 'replace (λ () (write (serialize o))))
(with-input-from-file f-name (λ () (deserialize (read)))))
 
(define cloned-family (duplicate-object-through-file the-family "objects.dat"))
 
(printf "The original family:\t~a~%" (send the-family ->string))
(printf "The cloned family:\t~a~%~%" (send cloned-family ->string))
(printf "objects.dat contains ----~%~a~%-------------------~%~%" (file->string "objects.dat"))
(printf "Clones are different?~%")
(define cloned-jack (first (get-field children cloned-family)))
(set-field! name cloned-jack "JACK")
(printf "Jack's name is:\t~s~%" (get-field name jack))
(printf "Clone's name is:\t~s~%~%" (get-field name cloned-jack))
(printf "Relationships are maintained?~%")
(define cloned-joan (second (get-field children cloned-family)))
(printf "Joan's description with siblings:\t~s~%" (send joan ->string #:show '(siblings)))
(printf "Clone's description with siblings:\t~s~%~%"
(send cloned-joan ->string #:show '(siblings)))
(printf "After Jack's renaming the cloned family is: ~a~%~%" (send cloned-family ->string))
(printf "Various descriptions of cloned John:~%")
(define cloned-john (get-field father cloned-family))
(printf "Just the name:\t~s~%" (send cloned-john ->string))
(printf "With siblings:\t~s (he hasn't any)~%" (send cloned-john ->string #:show '(siblings)))
(printf "With children:\t~s~%" (send cloned-john ->string #:show '(children)))
(printf "With both:\t~s~%" (send cloned-john ->string #:show '(siblings children)))</syntaxhighlight>
 
{{out}}
<pre>The original family: John + Jane -> Jack, Joan
The cloned family: John + Jane -> Jack, Joan
 
objects.dat contains ----
((3) 3 ((#"C:\\[...]\\Serializable-Objects.rkt" . deserialize-info:person%) (#"C:\\[...]\\Serializable-Objects.rkt" . deserialize-info:nuclear-family%) (#"C:\\[...]\\Serializable-Objects.rkt" . deserialize-info:parent%)) 4 ((q . #(())) #&0 (0 (c (? . 0) c "Joan" c (c (? . 1)))) (c (? . 1) c (? . 2))) ((1 0 (c (? . 0) c "Jack" c (c (? . 2))))) (1 (c (? . 0) c (2 (c (v! (c (? . 0) q "John" ())) c (? . 3))) c (2 (c (v! (c (? . 0) q "Jane" ())) c (? . 3))) c (? . 3))))
-------------------
 
Clones are different?
Jack's name is: "Jack"
Clone's name is: "JACK"
 
Relationships are maintained?
Joan's description with siblings: "Joan (Jack)"
Clone's description with siblings: "Joan (JACK)"
 
After Jack's renaming the cloned family is: John + Jane -> JACK, Joan
 
Various descriptions of cloned John:
Just the name: "John"
With siblings: "John" (he hasn't any)
With children: "John [JACK, Joan]"
With both: "John [JACK, Joan]"</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line># Reference:
# https://docs.raku.org/language/classtut
# https://github.com/teodozjan/perl-store
 
use v6;
use PerlStore::FileStore;
 
class Point {
has Int $.x;
has Int $.y;
}
 
class Rectangle does FileStore {
has Point $.lower;
has Point $.upper;
 
method area() returns Int {
($!upper.x - $!lower.x) * ( $!upper.y - $!lower.y);
}
}
 
my $r1 = Rectangle.new(lower => Point.new(x => 0, y => 0),
upper => Point.new(x => 10, y => 10));
say "Create Rectangle1 with area ",$r1.area();
say "Serialize Rectangle1 to object.dat";
$r1.to_file('./objects.dat');
say "";
say "take a peek on object.dat ..";
say slurp "./objects.dat";
say "";
say "Deserialize to Rectangle2";
my $r2 = from_file('objects.dat');
say "Rectangle2 is of type ", $r2.WHAT;
say "Rectangle2 area is ", $r2.area();</syntaxhighlight>
{{out}}
<pre>Create Rectangle1 with area 100
Serialize Rectangle1 to object.dat
 
take a peek on object.dat ..
Rectangle.new(lower => Point.new(x => 0, y => 0), upper => Point.new(x => 10, y => 10))
 
 
Deserialize to Rectangle2
Rectangle2 is of type (Rectangle)
Rectangle2 area is 100</pre>
 
=={{header|Ruby}}==
The core class <code>[http://www.ruby-doc.org/core/classes/Marshal.html Marshal]</code> handles object serialization. The <code>dump</code> method serializes an object, and the <code>load</code> method reconstitutes it.
<langsyntaxhighlight lang="ruby">class Being
def initialize(specialty=nil)
@specialty=specialty
Line 1,623 ⟶ 2,295:
end.join("\n\n")
)
puts "END LOADED DIVERSE COLLECTION"</langsyntaxhighlight>
 
=={{header|Rust}}==
Rust does not have inheritance, but this can be done with either enums or traits.
=== Enum ===
Dependencies:
<syntaxhighlight lang="toml">serde = { version = "1.0.89", features = ["derive"] }
bincode = "1.1.2"</syntaxhighlight>
 
<syntaxhighlight lang="rust">use std::fmt;
 
use bincode::{deserialize, serialize};
use serde::{Deserialize, Serialize};
 
#[derive(Debug, Serialize, Deserialize)]
enum Animal {
Dog { name: String, color: String },
Bird { name: String, wingspan: u8 },
}
 
impl fmt::Display for Animal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Animal::Dog { name, color } => write!(f, "{} is a dog with {} fur", name, color),
Animal::Bird { name, wingspan } => {
write!(f, "{} is a bird with a wingspan of {}", name, wingspan)
}
}
}
}
 
fn main() -> bincode::Result<()> {
let animals = vec![
Animal::Dog {
name: "Rover".into(),
color: "brown".into(),
},
Animal::Bird {
name: "Tweety".into(),
wingspan: 3,
},
];
 
for animal in &animals {
println!("{}", animal);
}
 
let serialized = serialize(&animals)?;
 
println!("Serialized into {} bytes", serialized.len());
 
let deserialized: Vec<Animal> = deserialize(&serialized)?;
 
println!("{:#?}", deserialized);
 
Ok(())
}</syntaxhighlight>
{{out}}
<pre>Rover is a dog with brown fur
Tweety is a bird with a wingspan of 3
Serialized into 57 bytes
[
Dog {
name: "Rover",
color: "brown"
},
Bird {
name: "Tweety",
wingspan: 3
}
]</pre>
=== Trait ===
Dependencies:
<syntaxhighlight lang="toml">serde = { version = "1.0.89", features = ["derive"] }
bincode = "1.1.2"
typetag = "0.1.1"</syntaxhighlight>
 
<syntaxhighlight lang="rust">use std::fmt::{self, Debug, Display};
 
use bincode::{deserialize, serialize};
use serde::{Deserialize, Serialize};
 
#[typetag::serde(tag = "animal")]
trait Animal: Display + Debug {
fn name(&self) -> Option<&str>;
fn feet(&self) -> u32;
}
 
#[derive(Debug, Deserialize, Serialize)]
struct Dog {
name: String,
color: String,
}
 
impl Display for Dog {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} is a dog with {} fur", self.name, self.color)
}
}
 
#[typetag::serde]
impl Animal for Dog {
fn name(&self) -> Option<&str> {
Some(&self.name)
}
 
fn feet(&self) -> u32 {
4
}
}
 
#[derive(Debug, Deserialize, Serialize)]
struct Bird {
name: String,
wingspan: u32,
}
 
impl Display for Bird {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} is a bird with a wingspan of {}",
self.name, self.wingspan
)
}
}
 
#[typetag::serde]
impl Animal for Bird {
fn name(&self) -> Option<&str> {
Some(&self.name)
}
 
fn feet(&self) -> u32 {
2
}
}
 
fn main() -> bincode::Result<()> {
let animals: Vec<Box<dyn Animal>> = vec![
Box::new(Dog {
name: "Rover".into(),
color: "brown".into(),
}),
Box::new(Bird {
name: "Tweety".into(),
wingspan: 3,
}),
];
 
for animal in &animals {
println!("{}", animal);
}
 
let serialized = serialize(&animals)?;
println!("Serialized into {} bytes", serialized.len());
 
let deserialized: Vec<Box<dyn Animal>> = deserialize(&serialized)?;
 
println!("{:#?}", deserialized);
 
Ok(())
}</syntaxhighlight>
{{out}}
<pre>Rover is a dog with brown fur
Tweety is a bird with a wingspan of 3
Serialized into 172 bytes
[
Dog {
name: "Rover",
color: "brown"
},
Bird {
name: "Tweety",
wingspan: 3
}
]</pre>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
''This example uses an experimental package, available from [http://wiki.tcl.tk/23444 The Tcler's Wiki].
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
package require TclOO::serializer 0.1
 
Line 1,679 ⟶ 2,527:
set obj [oo::deserialize [read $f]]
close $f
$obj printGreetings</langsyntaxhighlight>
 
=={{header|TXR}}==
 
TXR Lisp has good support for object serialization. The object file format for compiled files (<code>.tlo</code> files) depends on it.
 
<syntaxhighlight lang="txrlisp">(defstruct shape ()
(pos-x 0.0) (pos-y 0.0))
 
(defstruct circle (shape)
radius)
 
(defstruct ellipse (shape)
min-radius maj-radius)
 
(defvarl shapes (list (new circle radius 3.0)
(new ellipse min-radius 4.0 maj-radius 5.0)))
 
(put-line "original shapes:")
(prinl shapes)
 
(file-put "shapes.tl" shapes)
 
(put-line "dump of shapes.tl file:")
(put-line (file-get-string "shapes.tl"))
 
(put-line "object list read from file:")
(prinl (file-get "shapes.tl"))</syntaxhighlight>
 
{{out}}
 
<pre>original shapes:
(#S(circle pos-x 0.0 pos-y 0.0 radius 3.0) #S(ellipse pos-x 0.0 pos-y 0.0 min-radius 4.0 maj-radius 5.0))
dump of shapes.tl file:
(#S(circle pos-x 0.0 pos-y 0.0 radius 3.0) #S(ellipse pos-x 0.0 pos-y 0.0 min-radius 4.0 maj-radius 5.0))
 
object list read from file:
(#S(circle pos-x 0.0 pos-y 0.0 radius 3.0) #S(ellipse pos-x 0.0 pos-y 0.0 min-radius 4.0 maj-radius 5.0))</pre>
 
An object can be given a <code>print</code> method which has a Boolean argument whether to print "pretty" (meaning in some nicely formatted form for humans, not necessarily a serial notation readable by machine). A print method can return the <code>:</code> (colon) symbol to indicate that it declines to print; the default implementation should be used. With that it it possible to do
 
<syntaxhighlight lang="txrlisp">(defstruct shape ()
(pos-x 0.0) (pos-y 0.0))
 
(defstruct circle (shape)
radius
(:method print (me stream pretty-p)
(if pretty-p
(put-string `#<circle of radius @{me.radius} at coordinates (@{me.pos-x}, @{me.pos-y})>`)
:)))
 
(let ((circ (new circle radius 5.3)))
(prinl circ) ;; print machine readably
(pprinl circ)) ;; print pretty</syntaxhighlight>
 
{{out}}
 
<pre>#S(circle pos-x 0.0 pos-y 0.0 radius 5.3)
#<circle of radius 5.3 at coordinates (0, 0)></pre>
 
=={{header|Wren}}==
{{libheader|Wren-json}}
Currently, Wren's only facility for serializing objects is to use the above JSON module. Also this module can only 'stringify' objects of built-in types so we need to provide a suitable string representation for each user-defined class.
<syntaxhighlight lang="wren">import "./json" for JSON
import "io" for File, FileFlags
 
class Entity {
construct new(name) {
_name = name
}
 
name { _name }
 
// JSON representation
toString { "{\"name\": \"%(_name)\"}" }
 
// mimics the JSON output
print() { System.print(this.toString.replace("\"", "")) }
 
serialize(fileName) {
var o = JSON.parse(this.toString)
File.openWithFlags(fileName, FileFlags.writeOnly) { |file|
file.writeBytes("%(o)\n")
}
}
}
 
class Person is Entity {
construct new(name, age) {
super(name)
_age = age
}
 
// JSON representation
toString { "{\"name\": \"%(name)\", \"age\": \"%(_age)\"}" }
 
// mimics the JSON output
print() { System.print(this.toString.replace("\"", "")) }
 
serialize(fileName) {
var o = JSON.parse(this.toString)
File.openWithFlags(fileName, FileFlags.writeOnly) { |file|
file.writeBytes("%(o)\n")
}
}
}
 
// create file for serialization
var fileName = "objects.dat"
var file = File.create(fileName)
file.close()
 
System.print("Calling print methods gives:")
 
var e = Entity.new("John")
e.print()
e.serialize(fileName)
 
var p = Person.new("Fred", 35)
p.print()
p.serialize(fileName)
 
System.print("\nContents of objects.dat are:")
System.print(File.read(fileName))</syntaxhighlight>
 
{{out}}
<pre>
Calling print methods gives:
{name: John}
{name: Fred, age: 35}
 
Contents of objects.dat are:
{name: John}
{name: Fred, age: 35}
</pre>
 
=={{header|zkl}}==
zkl can serialize a "root class" (usually a file but any static (ie parentless) class) to bit bucket (such as File). This is done via reflection. The state of the class(es) are not stored so no image write/read. In the "normal" course of events, this isn't used, programs are compiled on the fly and run. However, there is extensive support to pre-compile and package files into applications or just pre-compile for faster load times (or to create an image that can be compiled into C code (which is done to package the compiler with the VM). When the compiler writes a class or app to a file, the preferred extension is ".zsc", which is what the Import method looks for. But no matter, we have ways ...
 
<syntaxhighlight lang="zkl">class [static] ARootClass{ // A top level class, no instances
class A{ self.println(" constructor"); } // a regular class
class B(A){ // ditto
var x;
fcn init(x=123){ self.x=x }
fcn toString{ "x is "+x }
}
}
 
ARootClass.B(456).println(); // create an instance
// prints:
Class(A) constructor
x is 456
 
f:=File("object.dat","wb");
Compiler.Asm.writeRootClass(ARootClass,f); // serialize to file
f.close();
 
f:=File("object.dat","rb");
rc:=Compiler.Asm.readRootClass(f); // read and re-create
// prints (readRootClass calls all constructors by default):
Class(A) constructor
f.close();
rc.B().println(); // create a new instance of B
// prints:
x is 123</syntaxhighlight>
 
 
{{omit from|AWK}}
Line 1,685 ⟶ 2,698:
{{omit from|Fortran}}
{{omit from|M4}}
{{omit from|Mathematica}}
{{omit from|Maxima}}
{{omit from|Metafont}}
{{omit from|Octave}}
{{omit from|PARI/GP}}
{{omit from|PureBasic}}<!-- |PureBasic does not allow serialization without extra add-ons. -->}}
{{omit from|Retro}}
{{omit from|REXX}}
{{omit from|TI-83 BASIC}}
{{omit from|TI-89 BASIC}} <!-- |Does not have user-defined data structures or objects. -->}}
{{omit from|ZX Spectrum Basic}}<!-- |Does not have user-defined data structures or objects. -->}}
2,122

edits