View Problem
Implement and use an Interface
Create a Serializable interface consisting of
* Accept a stream or handle or descriptor argument for the source or destination
* Save to destination or restore from source the properties or data members of the implementing class (restrict yourself to the primitive types
Next, create a Person class which has
Submit a new solution for clojure, cpp, fsharp, groovy ...
There are 6 other solutions in additional languages (fantom, haskell, perl, php ...)
'save' and 'restore' methods, each of which:
* Accept a stream or handle or descriptor argument for the source or destination
* Save to destination or restore from source the properties or data members of the implementing class (restrict yourself to the primitive types
'int' and 'string')
Next, create a Person class which has
'name' and 'age' properties or data members and implements this interface. Instantiate a Person object, save it to a serial stream, and instantiate a new Person object by restoring it from the serial stream.
clojure
(defn person [name age]
{:name name :age age})
(defn show [p]
(println (format "Name=%s Age=%d" (:name p) (:age p))))
(defn save [p filename]
(with-out-writer filename (pr p)))
(defn restore [filename]
(read (PushbackReader. (reader filename))))
(let [p (person "Ken" 38)]
(show p)
(save p *person-fn*))
(let [ser-p (restore *person-fn*)]
(show ser-p))
{:name name :age age})
(defn show [p]
(println (format "Name=%s Age=%d" (:name p) (:age p))))
(defn save [p filename]
(with-out-writer filename (pr p)))
(defn restore [filename]
(read (PushbackReader. (reader filename))))
(let [p (person "Ken" 38)]
(show p)
(save p *person-fn*))
(let [ser-p (restore *person-fn*)]
(show ser-p))
cpp
struct person
{
person(){}
person(const string &name, int age) : name_(name), age_(age) {}
string name_;
int age_;
template<typename Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & name_ & age_;
}
};
int main()
{
const char *fn = "filename.txt";
person k("Ken", 38);
{
ofstream ofs(fn);
archive::text_oarchive oa(ofs);
oa << k;
}
person restored_person;
{
ifstream ifs(fn);
archive::text_iarchive ia(ifs);
ia >> restored_person;
}
cout << "Name : " << restored_person.name_ << endl
<< "Age : " << restored_person.age_ << endl;
}
{
person(){}
person(const string &name, int age) : name_(name), age_(age) {}
string name_;
int age_;
template<typename Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & name_ & age_;
}
};
int main()
{
const char *fn = "filename.txt";
person k("Ken", 38);
{
ofstream ofs(fn);
archive::text_oarchive oa(ofs);
oa << k;
}
person restored_person;
{
ifstream ifs(fn);
archive::text_iarchive ia(ifs);
ia >> restored_person;
}
cout << "Name : " << restored_person.name_ << endl
<< "Age : " << restored_person.age_ << endl;
}
fsharp
// Since everyone else is using built-in functionality instead of
// defining an interface as required, I won't buck the trend.
// Maybe this problem should be named "Use serialization features" instead
// of "Implement and use an Interface"
open System
open System.IO
open System.Runtime.Serialization.Formatters.Binary
[<Serializable>]
type Person(name:string, age:int) =
member this.Name = name
member this.Age = age
let serialize x =
use ms = new MemoryStream()
let bf = new BinaryFormatter()
bf.Serialize(ms, x)
ms.ToArray()
let deserialize<'a> bytes =
use ms = new MemoryStream(bytes:byte[])
let bf = new BinaryFormatter()
bf.Deserialize(ms) :?> 'a
let before = Person("Joel", 35)
let bytes = serialize before
let after = deserialize<Person> bytes
printfn "Before: %s, %i" before.Name before.Age
printfn "After: %s, %i" after.Name after.Age
// defining an interface as required, I won't buck the trend.
// Maybe this problem should be named "Use serialization features" instead
// of "Implement and use an Interface"
open System
open System.IO
open System.Runtime.Serialization.Formatters.Binary
[<Serializable>]
type Person(name:string, age:int) =
member this.Name = name
member this.Age = age
let serialize x =
use ms = new MemoryStream()
let bf = new BinaryFormatter()
bf.Serialize(ms, x)
ms.ToArray()
let deserialize<'a> bytes =
use ms = new MemoryStream(bytes:byte[])
let bf = new BinaryFormatter()
bf.Deserialize(ms) :?> 'a
let before = Person("Joel", 35)
let bytes = serialize before
let after = deserialize<Person> bytes
printfn "Before: %s, %i" before.Name before.Age
printfn "After: %s, %i" after.Name after.Age
groovy
// Built-in functionality but with slightly different names. Showing usage:
class Person implements Serializable { String name; int age }
p1 = new Person(name:'John', age:21)
p2 = null
output = new ByteArrayOutputStream() // or FileOutputStream, etc.
output.withObjectOutputStream { oos -> oos << p1 }
input = new ByteArrayInputStream(output.toByteArray())
input.withObjectInputStream(getClass().classLoader){ ois -> p2 = ois.readObject() }
assert p2.name == 'John'
assert p2.age == 21
class Person implements Serializable { String name; int age }
p1 = new Person(name:'John', age:21)
p2 = null
output = new ByteArrayOutputStream() // or FileOutputStream, etc.
output.withObjectOutputStream { oos -> oos << p1 }
input = new ByteArrayInputStream(output.toByteArray())
input.withObjectInputStream(getClass().classLoader){ ois -> p2 = ois.readObject() }
assert p2.name == 'John'
assert p2.age == 21
java 1.3 and above
// Serialization to a file
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean equals(Object obj) {
if(obj == this) return true;
if(obj instanceof Person) {
Person p = (Person) obj;
return (p.getName().equals(this.getName())
& p.getAge() == this.getAge());
}
return false;
}
public String toString() {
return "Name: " + name + ", age: " + age;
}
}
Person person = new Person();
person.setName("Gaylord Focker");
person.setAge(21);
try {
File file = new File("ser.obj");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(person);
oos.close();
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Person deserializedPerson = (Person) ois.readObject();
ois.close();
System.out.println(deserializedPerson);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean equals(Object obj) {
if(obj == this) return true;
if(obj instanceof Person) {
Person p = (Person) obj;
return (p.getName().equals(this.getName())
& p.getAge() == this.getAge());
}
return false;
}
public String toString() {
return "Name: " + name + ", age: " + age;
}
}
Person person = new Person();
person.setName("Gaylord Focker");
person.setAge(21);
try {
File file = new File("ser.obj");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(person);
oos.close();
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Person deserializedPerson = (Person) ois.readObject();
ois.close();
System.out.println(deserializedPerson);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ocaml
(* in OCaml, interfaces are class types, and have nothing to do with inheritance,
so I'm not sure what's the correct answer to this problem (if any) *)
class type serializable =
object
method save: out_channel -> unit
method restore: in_channel -> unit
end
class person name age =
object
val mutable my_name = name
val mutable my_age = age
method save oc = output_value oc my_name; output_value oc my_age
method restore ic = my_name <- input_value ic; my_age <- input_value ic
method print = Printf.printf "I'm %s, %d\n" my_name my_age
end
let transfer (o1: serializable) (o2: serializable) =
let temp_filename = "_person" in
let backing_store_save = open_out_bin temp_filename in
o1#save backing_store_save;
close_out backing_store_save;
let backing_store_restore = open_in_bin temp_filename in
o2#restore backing_store_restore;
close_in backing_store_restore
let o = new person "john" 42 in
let o2 = new person "nobody" 0 in
transfer (o :> serializable) (o2 :> serializable);
o2#print
so I'm not sure what's the correct answer to this problem (if any) *)
class type serializable =
object
method save: out_channel -> unit
method restore: in_channel -> unit
end
class person name age =
object
val mutable my_name = name
val mutable my_age = age
method save oc = output_value oc my_name; output_value oc my_age
method restore ic = my_name <- input_value ic; my_age <- input_value ic
method print = Printf.printf "I'm %s, %d\n" my_name my_age
end
let transfer (o1: serializable) (o2: serializable) =
let temp_filename = "_person" in
let backing_store_save = open_out_bin temp_filename in
o1#save backing_store_save;
close_out backing_store_save;
let backing_store_restore = open_in_bin temp_filename in
o2#restore backing_store_restore;
close_in backing_store_restore
let o = new person "john" 42 in
let o2 = new person "nobody" 0 in
transfer (o :> serializable) (o2 :> serializable);
o2#print
python 2.6
import pickle
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "Name: {name}, age: {age}".format(name=self.name, age=self.age)
person = Person("Gaylord Focker", 21)
with open("person.pickle", "wb") as outstream:
pickle.dump(person, outstream)
with open("person.pickle", "rb") as instream:
deserialized_person = pickle.load(instream)
print(deserialized_person)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "Name: {name}, age: {age}".format(name=self.name, age=self.age)
person = Person("Gaylord Focker", 21)
with open("person.pickle", "wb") as outstream:
pickle.dump(person, outstream)
with open("person.pickle", "rb") as instream:
deserialized_person = pickle.load(instream)
print(deserialized_person)
scala
class Person (var name: String, var age: Int) extends Serializable
val p1 = new Person("John", 21)
val output = new ByteArrayOutputStream()
val oos = new ObjectOutputStream(output)
oos.writeObject(p1)
oos.flush
oos.close
val input = new ByteArrayInputStream(output.toByteArray())
val ois = new ObjectInputStream(input)
val p2 = ois.readObject().asInstanceOf[Person]
assert(p2.name == "John")
assert(p2.age == 21)
val p1 = new Person("John", 21)
val output = new ByteArrayOutputStream()
val oos = new ObjectOutputStream(output)
oos.writeObject(p1)
oos.flush
oos.close
val input = new ByteArrayInputStream(output.toByteArray())
val ois = new ObjectInputStream(input)
val p2 = ois.readObject().asInstanceOf[Person]
assert(p2.name == "John")
assert(p2.age == 21)
Submit a new solution for clojure, cpp, fsharp, groovy ...
There are 6 other solutions in additional languages (fantom, haskell, perl, php ...)




