Class Serialization in Perl

Serialization in Perl is the process of saving a class with multiple data types to a scalar (string of bytes). This can be used to save objects to a file or to transmit objects across the Internet. For this article I am going to describe the basics of creating a class in Perl and serialize it using the following packages: Data::Dumper, FreezeThaw, PHP::Serialization, and XML::Dumper.

Data types in Perl

Before we serialize anything we first need to learn a bit about the data types in Perl. There are only three data types in Perl, these are scalars, arrays and hash tables. Below is an example of each.

$myScalar = This is a Scalar;
@myArray = (Element zero,Element one,Element Two);
%myHash = ( keyOne => Data1, keyTwo => Data2);

print Scalar Data: . $myScalar . \n;
print Array element at index 1: . @myArray[1] . \n;
print Hash at KeyOne: . $myHash{keyOne} . \n;

Output:

Scalar Data: This is a Scalar
Array element at index 1: Element one
Hash at KeyOne: Data1

Like in C and C++, you can also have references to the data in each data type. The reference is not the data its self, but a location where the data can be found. By using special syntax the data can be retrieved from the reference itself.

$scalarReference = \$myScalar;
$arrayReference = \@myArray;
$hashReference = \%myHash;

print Scalar Reference: $scalarReference \n;
print Array Reference: $arrayReference \n;
print Hash Reference: $hashReference \n;

#Different ways to print the referenced data

print Scalar Data: . ${$scalarReference} . \n; #Or
print Scalar Data: . $$scalarReference . \n;

print Array element at index 1: . @{$arrayReference}[1] . \n; #Or
print Array element at index 1: . @$arrayReference[1] . \n; #Or
print Array element at index 1: . $arrayReference->[1] . \n;

print Hash at KeyOne: . ${$hashReference}{keyOne} . \n; #Or
print Hash at KeyOne: . $hashReference->{keyOne} . \n;

Output:

Scalar Reference: SCALAR(0x8153600)
Array Reference:  ARRAY(0x8153630)
Hash Reference:   HASH(0x8153690)
Scalar Data: This is a Scalar
Scalar Data: This is a Scalar
Array element at index 1: Element one
Array element at index 1: Element one
Array element at index 1: Element one
Hash at KeyOne: Data1
Hash at KeyOne: Data1

Classes in Perl

Perl was not originally designed to be an object oriented language, although it is possible to use it as one by using the following techniques. A class in Perl is basically just a module that returns a reference to a hash containing the data that is accessible to the class. This referenced is then “blessed” which means that it is bounded to the module. Perl uses some syntactical sugar to make this processes easy. Below is a test class in Perl that uses each of the data types. This class was created to test the serialization of each package.

#!/usr/bin/perl
#####################################################
#Author:Evan Salazar
#This is a just a simple perl class that uses
#different data types to be used in serialization
#####################################################
package TestClass;
use strict; #Normally use to keep data clean

#The Constructor
sub new {
print Creating the Class \n;

my $obj = {
name => {firstName => none, lastName => none}, #Test Hash
email => none@none.com, #Test Scalar
skills => undef, #Test array
gpgKey => }; #Binary Data
bless($obj);

return $obj;

}

#Set the Contact Name
sub setName {
my $self = shift;
$self->{name}->{firstName} = $_[0];
$self->{name}->{lastName} = $_[1];
}

#Set the E-Mail
sub setEmail {
my $self = shift;
$self->{email} = $_[0];
}

#Set the Skills
sub setSkills {
my $self = shift;
$self->{skills} = \@_;
}

#Set the GPG Key
sub setGpgKey {
my $self = shift;
$self->{gpgKey} = $_[0];
}

#Print all of the class Data
sub printAll {

my $self = shift;

#Print Full Name
print Name: .
$self->{name}->{firstName} .
.
$self->{name}->{firstName} . \n;
#Print E-Mail
print E-Mail: . $self->{email} . \n;

#Print Skills
print Skills: ;
for(my $i=0;$i<=$#{$self->{skills}};$i++) {
print $self->{skills}[$i] . ;
}
print \n;
print GPG Key: . unpack(H*,$self->{gpgKey}) . \n

}

1;

Perl Serialization Methods

There is no built in serialization in Perl, therefor serialization has to be done with an external package. After searching CPAN I found the following packages.

  • Data::Dumper – Serialize data into Perl code that can then be unserialized using the eval() procedure.
  • FreezeThaw – Converts objects to a string for data storage and retrieval.
  • PHP::Serialization – Serialize using a method that is compatible with the serialize() method in PHP.
  • XML::Dumper – Serialize to XML. Does not work with binary data.

These packages can be installed by downloading the source code and compiling or by using the following ‘cpan’ commands.

sudo cpan install Data::Dumper
sudo cpan install FreezeThaw
sudo cpan install PHP::Serialization
sudo cpan install XML::Dumper

Serializing TestClass

Below is a program that will serialize TestClass initialized with some sample data. The data will be serialized using all 4 classes.

#!/usr/bin/perl
#####################################################
#Author: Evan Salazar
#Serialize The data in TestClass
#####################################################
use strict;
use Storable;
use PHP::Serialization;
use FreezeThaw;
use TestClass;
use XML::Dumper;
use Data::Dumper;

#Create the New Test Class
my $myclass = TestClass::new();

#Fill the Test Class with data
$myclass->setName(Evan,Salazar);
$myclass->setEmail(esalazar1981@gmail.com);
$myclass->setSkills(Perl,PHP,Java,C,C++);
#—–Comment out to use XML::Dumper————–#
$myclass->setGpgKey(pack(H*,11061398fe828dcd83a4b9a79594c399)); #Not really my key but 128bits of random data

#Open File for wrting Serialized Data
open(PHPSER, >phpser);
open(FREEZETHAW, >freezeThaw);
open(XMLDUMPER, >xmldumper.xml);
open(DATADUMPER, >dataDumper.pl);

#Serialize Using Data::Dumper
print Data::Dumper\n;
print DATADUMPER Data::Dumper::Dumper($myclass);

#Serialize Using FreezeThaw
print FreezeThaw\n;
print FREEZETHAW FreezeThaw::freeze($myclass);

#Serialize Using PHP::Serialization
print PHP::Serializatoin\n;
print PHPSER PHP::Serialization::serialize($myclass);

#Serialize Using XML::Dumper
print XML::Dumper\n;
my $dump = new XML::Dumper;
print XMLDUMPER $dump->pl2xml($myclass);

This is the output from each method:

dataDumper.pl

<br /> $VAR1 = bless( {<br /> ‘email’ => ‘esalazar1981@gmail.com’,<br /> ‘skills’ => [<br /> ‘Perl’,<br /> ‘PHP’,<br /> ‘Java’,<br /> ‘C’,<br /> ‘C++'<br /> ],<br /> ‘name’ => {<br /> ‘firstName’ => ‘Evan’,<br /> ‘lastName’ => ‘Salazar’<br /> },<br /> ‘gpgKey’ => ‘���������Ù’<br /> }, ‘TestClass’ );<br />

FreezeThaw

<br /> FrT;@1|>>0|$9|TestClass%8|$5|email$6|gpgKey$4|name$6|skills$22|esalazar1981@gmail.com$16|���������Ù%4|$9|firstName$8|lastName$4|Evan$7|Salazar@5|$4|Perl$3|PHP$4|Java$1|C$3|C++<br />

phpser

<br /> O:9:”TestClass”:4:{s:5:”email”;s:22:”esalazar1981@gmail.com”;s:6:”skills”;a:5:{i:0;s:4:”Perl”;i:1;s:3:”PHP”;i:2;s:4:”Java”;i:3;s:1:”C”;i:4;s:3:”C++”;}s:4:”name”;a:2:{s:9:”firstName”;s:4:”Evan”;s:8:”lastName”;s:7:”Salazar”;}s:6:”gpgKey”;s:16:”���������Ù”;}<br />

xmldumper.xml

</p> <perldata> <hashref blessed_package=”TestClass” memory_address=”0x8314de4″><br /> <item key=”email”>esalazar1981@gmail.com</item><br /> <item key=”gpgKey”>���������Ù</item><br /> <item key=”name”><br /> <hashref memory_address=”0x8152c28″><br /> <item key=”firstName”>Evan</item><br /> <item key=”lastName”>Salazar</item><br /> </hashref><br /> </item><br /> <item key=”skills”><br /> <arrayref memory_address=”0x823bcf0″><br /> <item key=”0″>Perl</item><br /> <item key=”1″>PHP</item><br /> <item key=”2″>Java</item><br /> <item key=”3″>C</item><br /> <item key=”4″>C++</item><br /> </arrayref><br /> </item><br /> </hashref> </perldata>

Unserializing the Data

Below is the program that will unseralize the data from the previous program. Note that any binary data will not be unseralized using XML::Dumper. If you need to serialize binary data with this package, consider first encoding it using UUencode or base64 encode.

#!/usr/bin/perl
#####################################################
#Author: Evan Salazar
#Unserialize the data in TestClass
#####################################################
use strict;
use Storable;
use PHP::Serialization;
use FreezeThaw;
use TestClass;
use XML::Dumper;
use Data::Dumper;

#Set Slurp mode for reading
local($/) = undef;

#Open File for reading Serialized Data
open(PHPSER, phpser);
open(FREEZETHAW, freezeThaw);
open(XMLDUMPER, xmldumper.xml);
open(DATADUMPER, dataDumper.pl);

#Unserialize Using Data::Dumper
print Data::Dumper\n;
my $dataDumper = <DATADUMPER>;
#print $dataDumper
my $VAR1;
eval($dataDumper); #Data is stored into variable $VAR1
$VAR1->printAll;
print \n;

#Unserialize Using FreezeThaw
print FreezeThaw\n;
my $freezeThaw = <FREEZETHAW>;
#print $freezeThaw;
my ($classFreeze) = FreezeThaw::thaw($freezeThaw);
$classFreeze->printAll;
print \n;

#Unserialize Using PHP::Serialization
print PHP::Serializatoin\n;
my $phpser = <PHPSER>;
#print $phpser;
my $classPHP = PHP::Serialization::unserialize($phpser);
bless($classPHP,TestClass);
$classPHP->printAll;
print \n;

#Unserialize Using XML::Dumper
print XML::Dumper\n;
my $xmlDumper = <XMLDUMPER>;
my $dump = new XML::Dumper;
my $xmlClass = $dump->xml2pl($xmlDumper);
$xmlClass->printAll;

Program Output

Data::Dumper
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key: 11061398fe828dcd83a4b9a79594c399

FreezeThaw
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key: 11061398fe828dcd83a4b9a79594c399

PHP::Serializatoin
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key: 11061398fe828dcd83a4b9a79594c399

XML::Dumper

not well-formed (invalid token) at line 4, column 21, byte 148 at /usr/lib/perl5/XML/Parser.pm line 187

If you remove the binary data you will get

Data::Dumper
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

FreezeThaw
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

PHP::Serializatoin
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

XML::Dumper
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

Conclusion

All of these methods worked well for the given class, although binary to ASCII encoding is necessary for XML serialization. I personally prefer XML serialization because the data can be used with a wide variety of languages. Also XML serialization is human readable.

AC Motor / Generator Project

This project started one night while I was lying in bed trying to visualize how an AC motor worked. I knew that it was different from a DC motor as in it did not require brushes and the speed was controlled by frequency instead of voltage. After some research I came up with this project to better my understanding of AC motors.

AC Theory:
AC Current is different from DC in that the polarity is constantly inverting in a given period. For example: Lets say you have a standard battery hooked up to a volt meter. Normally you would connect the positive lead to the positive terminal of the battery as well as the negative lead to the negative terminal. If you wish to generate an AC current you would connect the leads normally for half a second and then invert them (where the positive terminal is connected to the negative lead and the negative terminal is connected to the positive lead) for another half second. If you constantly repeat this process you will have an AC current operating at one hertz (1hz). Where a hertz is 1 / Period. The period is the time the current is positive plus the time it is negative in one cycle, so in our case 0.5s + 0.5s = 1s per period. In America AC voltage to your home is typically 110 Volts at 60hz in a smooth sine wave.

Quick Magnet Theory:
A more in depth theory about magnets can be found here. For our practical purposes all we need to know is that a magnet has two poles, north and south. Poles attract each other when placed from north to south and repel when placed north to north or south to south.

Quick Electromagnet Theory:
An electromagnet is a magnet that is created with a coil. When current passes through the coil a magnetic flux is created. Conversely when a magnetic field passes through the coil a current is created. More information can be found here.

AC Motor/Generator theory
Most of the information I used to design this motor came from this page. I placed six magnets on the rotor with alternating poles and placed 6 coils in the housing with the polarities also alternating. When an AC current is run through the coils the polarity will switch the magnets poles from north to south at the given frequency. Therefor the rotor will turn so that the poles on the magnets will always line up.

Construction:

After I had a good idea of how I was going to build this motor I needed to collect parts. I already had some bolts that I can use for coils along with copper magnet wire. So off to Hobby Lobby. There I found some ultra strong magnets along with construction Styrofoam.

The base for the motor

Dividing the rotor into 6 sections

The completed measurements

Coil winding:
At this stage I had to determine how strong of an electromagnet I needed for the magnets I bought. Since the magnets are rated at “10” in strength, I had to create a electromagnet with enough magnetic flux to successfully repel the magnet.

Along with determining the proper coil windings, I also had to label the polarity of each magnet. I used a +5V DC power supply to test the coil. After experimenting I decided to use 350 turns with 30 gauge wire.

Once the polarity was determined for the magnets, I placed them in the rotor with hot glue.
The base fully assembled

The base with coils.

After the unit was fully assembled it was time to test it out. First I tested to see if spinning the rotor would generate an AC current. I wired all of the coils in series and hooked them up to the oscilloscope. Spinning the rotor by hand produced a rough sine wave at a about 100mv. Now it is time to try powering the motor. To generate a AC current I used a HP 200A audio oscillator at around 50hz. This device cannot supply much current so I ran it at high voltage (70v) through a step down transformer (110V to 12.6-0-12.6). After playing with lining up the coils I was able to successfully power the motor.

A Video of the Motor running can be found here