|
Net::Peep::Data |
Net::Peep::Data - Base class for Peep data objects.
package Net::Peep::Data::Subclass;
use Net::Peep::Data;
@ISA = qw(Net::Peep::Data);
sub new {
my $self = shift;
my $class = ref($self) || $self;
my $this = $class->SUPER::new();
bless $this, $class;
} # end sub new
sub Name { return 'general'; } # end sub Name
sub Attributes {
my $self = shift;
my %attributes = ( version=>1,sound_path=>1 );
return wantarray ? %attributes : \%attributes;
} # end sub Attributes
For more information, read on.
The Net::Peep::Data class provides both explicitly defined and
autoloaded methods used by Peep data classes.
Included are methods used both to serialize and deserialize XML objects representing Peep data.
Subclasses of the Net::Peep::Data class are used to describe Peep data
internally, including configuration, theme, and notification information.
The Net::Peep::Data class is intended to be a superclass inherited by a
class or set of classes that represent a data structure that can be
represented with XML.
Net::Peep::Data comes with two important public methods: deserialize()
and serialize().
The deserialize() method takes an XML string as its sole argument and
returns an object structure representing the XML data.
<user>
<firstname>Collin</firstname>
<lastname>Starkweather</lastname>
<username>starky</username>
<credit_card>
<issuer>American Express</issuer>
<number>xxxx xxxx xxxx xxxx</number>
</credit_card>
<credit_card>
<issuer>Discover</issuer>
<number>xxxx xxxx xxxx xxxx</number>
</credit_card>
</user>
Here we have a structure representing a user who has several credit cards.
The Net::Peep::Data class represents each level of an XML heirarchy with a
separate class while attributes within a level are represented by methods with
corresponding names. We are therefore going to generate two classes to
represent this data: A user class and a credit card class. The user class
will have three attributes: firstname, lastname, and username. In
addition, each user may have several credit cards associated with it. The
credit card class will have two attributes: issuer and number.
Let's create the user class first. The user class will define its attributes
(firstname, lastname, and username) in an Attributes method that
will override the Net::Peep::Data Attributes method. In addition, for
the credit_card class, we'll have a Handler method to define the handler
for the credit_card attribute.
package User;
use Net::Peep::Data;
use CreditCard;
@ISA = qw(Net::Peep::Data);
sub new {
my $self = shift;
my $class = ref($self) || $self;
my $this = $class->SUPER::new();
bless $this, $class;
} # end sub new
sub Name { return 'user'; } # end sub Name
sub Attributes {
my $self = shift;
my %attributes = ( firstname=>1,lastname=>1,username=>1 );
return wantarray ? %attributes : \%attributes;
} # end sub Attributes
sub Handlers {
my $self = shift;
my %handlers = (credit_card => 'CreditCard');
return wantarray ? %handlers : \%handlers;
} # end sub Handlers
Now we'll define the credit card class:
package CreditCard;
use Net::Peep::Data;
@ISA = qw(Net::Peep::Data);
sub new {
my $self = shift;
my $class = ref($self) || $self;
my $this = $class->SUPER::new();
bless $this, $class;
} # end sub new
sub Name { return 'credit_card'; } # end sub Name
sub Attributes {
my $self = shift;
my %attributes = ( issuer=>1,number=>1 );
return wantarray ? %attributes : \%attributes;
} # end sub Attributes
That's all there is to it. Now let's take a look at how to use these classes to work with the XML data.
First, we'll instantiate a User object. Next, we'll ``deserialize,'' or
parse and lex, the XML string $xml. After parsing the XML string, we'll use
the User and CreditCard objects to access and modify the data. Finally,
we'll write out the modified data by ``serializing'' it.
my $xml = <<"eop";
<user>
<firstname>Collin</firstname>
<lastname>Starkweather</lastname>
<username>starky</username>
<credit_card>
<issuer>American Express</issuer>
<number>xxxx xxxx xxxx xxxx</number>
</credit_card>
<credit_card>
<issuer>Discover</issuer>
<number>xxxx xxxx xxxx xxxx</number>
</credit_card>
</user>
eop
use User;
# instantiate a user object
my $user = new User;
$user->deserialize($xml);
That's all there is to it. The $user object is now populated with
attributes and handlers that represent the XML data.
For example, to obtain the user name of the user whose data we just deserialized, simply
my $username = $user->username();
Note that whenever an attribute or handler is defined multiple times, the corresponding method will return an array or reference to an array rather than a simple scalar.
Thus, if the user had multiple user names
<user>
...
<username>starky</username>
<username>cstarkweather</username>
...
</user>
we would have had to obtain the user's user names with something like
my @usernames = $user->username();
If you don't know whether your data will have multiple occurances of an
attribute, but you only want one, you can use the following idiom (which you
can find throughout the Net::Peep::Data::* classes):
my ($username) = $user->username();
With that in mind, we will obtain the user's credit card information with a
call to the credit_card() method:
my @credit_cards = $user->credit_card();
Each element of the @credit_cards array is a CreditCard object. We can
get the issuer of each credit card by calling that object's issuer method:
for my $cc (@credit_cards) {
print "Found issuer: ", $cc->issuer(), "\n";
}
This loop will print out
Found issuer: American Express
Found issuer: Discover
$user->firstname("Joe");
Our user's first name is now Joe. We could also add a credit card to Mr.
Starkweather's list of credit cards with the addToPool method, which adds
an object to another object's object pool (I hope that makes sense!):
my $cc = new CreditCard;
$cc->issuer("Visa");
$cc->number("xxxx xxxx xxxx xxxx");
$user->addToPool('credit_card',$cc);
Now the loop
for my $cc (@credit_cards) {
print "Found issuer: ", $cc->issuer(), "\n";
}
will print
Found issuer: American Express
Found issuer: Discover
Found issuer: Visa
serialize() method:
my $xml = $user->serialize();
None by default.
new() - The constructor
deserialize($xml) - Must be overridden in any subclass. Will parse the XML string $xml and return the object representation of the XML data structure. See section L<SERIALIZING AND DESERIALIZING XML> for more information.
serialize() - Must be overridden in any subclass. Will translate any object drived from a subclass into its XML representation.
Attributes() - Must be overridden in any subclass with a method that defines a hash of attributes.
Handlers() - Must be overridden in any subclass with a method that defines a hash of handlers.
Name() - Must be overridden in any subclass with a method that defines the name of the XML element the class should parse.
See also Net::Peep::Data::Pool, from which this class inherits.
Collin Starkweather <collin.starkweather@colorado.edu>
Copyright (C) 2001
perl(1), peepd(1), Net::Peep::Conf, Net::Peep::Parser.
|
Net::Peep::Data |