home *** CD-ROM | disk | FTP | other *** search
- package Data::JavaScript::LiteObject;
- use strict;
- use vars qw($VERSION $JSVER);
- $VERSION = '1.04';
-
- sub import{
- no strict 'refs';
- shift;
- $JSVER = shift || 1.0;
- *{"@{[scalar caller()]}::jsodump"} = \&jsodump;
- }
-
- sub jsodump {
- my %opts = @_;
- my(@keys, $obj, @objs, $EOL, $EOI, @F);
-
- unless( $opts{protoName} && $opts{dataRef} ){
- return warn("// Both protoName and dataRef must be supplied");
- }
-
- ($EOI, $EOL) = $opts{explode} ? ("$/\t")x2 : ('', ' ');
-
- if( ref($opts{dataRef}) eq "ARRAY" ){
- my $i=0;
- $opts{dataRef} = {map {$opts{protoName}.$i++=>$_} @{$opts{dataRef}} };
- }
- #NOT elsif
- if( ref($opts{dataRef}) eq "HASH" ){
- if( ref($opts{attributes}) eq "ARRAY" ){
- @keys = @{$opts{attributes}};
- }
- else{
- @keys = sort { $a cmp $b } keys
- %{$opts{dataRef}->{(sort keys %{$opts{dataRef}})[0]}};
- }
- }
- else{
- warn("// Unknown reference type, attributes"); return;
- }
-
- push @F, "function $opts{protoName} (", join(', ', @keys) ,") {$/\t";
- push @F, map("this.$_ = $_;$EOL", @keys);
- push @F, "}$/";
-
- foreach $obj ( sort keys %{$opts{dataRef}} ){
- push @F, "$obj = new $opts{protoName}($EOI";
- push @F, join(",$EOL",
- map(datum($opts{dataRef}->{$obj}->{$_}), @keys) ).$EOL;
- push @F, ");$/";
- push @objs, $obj;
- }
-
- if( defined($opts{listObjects}) ){
- push @F, "$opts{listObjects} = new Array($EOI",
- join(",$EOL", map("'$_'", @objs)), ");$/";
- }
-
- if( defined($opts{lineIN}) ){
- local $. = $opts{lineIN}+1;
- @F = split($/, join('', @F));
- foreach ( @F ) {
- $_ .= $/ . '// '. ++$. unless (++$.-$opts{lineIN}) %5;
- $_ .= $/;
- }
- ${$opts{lineOUT}} = $.;
- unshift @F, '// '. ($opts{lineIN}+1) .$/;
- }
- return @F;
- }
-
- sub datum {
- local $_ = shift() || '';
- my $val;
-
- if ( ref eq "ARRAY" ) {
- $val = $JSVER >= 1.2 ?
- "[" . join(',',
- map /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ ?
- $_ : do{ s/'/\\'/g; qq('$_') }, @{$_})
- . "]"
- :
-
- "new Array(" . join(',',
- map /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ ?
- $_ : do{ s/'/\\'/g; qq('$_') }, @{$_})
- . ")";
-
- }
- elsif( $val = $_, $val !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ ){
- s/'/\\'/g;
- $val = qq('$_');
- }
-
- return $val;
- }
-
- 1;
- __END__
-
- =pod
-
- =head1 NAME
-
- Data::JavaScript::LiteObject - lightweight data dumping to JavaScript
-
- =head1 SYNOPSIS
-
- use Data::JavaScript:LiteObject;
- #OR
- use Data::JavaScript:LiteObject '1.2';
-
- %A = (protein => 'bacon',
- condiments => 'mayonaise',
- produce => [qw(lettuce tomato)]);
- %B = (protein => 'peanut butter',
- condiments => 'jelly');
- @lunch = (\%A, \%B);
- %lunch = (BLT=>\%A, PBnJ=>\%B);
-
- jsodump(protoName => "sandwich",
- dataRef => \%lunch
- attributes => [qw(condiments protein produce)]);
-
- =head1 DESCRIPTION
-
- This module was inspired by L<Data::JavaScript>, which while incredibly
- versatile, seems rather brute force and inelegant for certain forms
- of data. Specifically a series of objects of the same class, which it
- seems is a likely use for this kind of feature. So this module was
- created to provide a lightweight means of producing configurable, clean
- and compact output.
-
- B<LiteObject> is used to format and output loh, hoh, lohol, and hohol.
- The output is JavaScript 1.0 compatible, with the limitation that none
- of the properties be a single-element array whose value is a number.
- To lift this limitation pass use the extra value I<'1.2'>, which will
- generate JavaScript 1.2 compatible output.
-
- One function, B<jsodump>, is exported. B<jsodump> accepts a list of named
- parameters; two of these are required and the rest are optional.
-
- =head2 Required parameters
-
- =over 4
-
- =item C<protoName>
-
- The name to be used for the prototype object function.
-
- =item C<dataRef>
-
- A reference to an array of hashes(loh) or hash of hashes(hoh) to dump.
-
- =back
-
- =head2 Optional parameters
-
- =over 4
-
- =item C<attributes>
-
- A reference to an array containing a list of the object attributes
- (hash keys). This is useful if every object is not guaranteed to
- posses a value for each attribute.
- It could also be used to exclude data from being dumped.
-
- =item C<explode>
-
- A scalar, if true output is one I<attribute> per line.
- The default; false; is one I<object> per line.
-
- =item C<lineIN>
-
- A scalar, if true output is numbered every 5 lines. The value provided
- should be the number of lines printed before this output.
- For example if a CGI script included:
-
- print q(<html>
- <head>
- <title>Pthbb!!</title>
- <script language=javascript>);>
- jsodump(protoName => "sandwich",
- dataRef => \@lunch,
- lineIN => 4);
-
- The client would see:
-
- <html>
- <head>
- <title>Pthbb!!</title>
- <script language=javascript>
- // 5
- function sandwich (condiment, produce, protein) {
- this.condiment = condiment; this.produce = produce; this.protein = protein; }
- BLT = new sandwich('mayonaise', new Array('lettuce','tomato'), 'bacon' );
- PBnJ = new sandwich('jelly', '', 'peanut butter' );
- // 10
-
- making it easier to read and/or debug.
-
- =item C<lineOUT>
-
- A reference to a scalar. B<jsodump> will set the scalar's value to the number
- of the last line of numbered output produced when lineIN is specified. Thus
- you may pass the scalar to a subsequent call to B<jsodump> as the value of
- lineIn for continuous numbering.
- For example:
-
- jsodump(protoName => "sandwich",
- dataRef => \@lunch,
- lineIN => 4,
- lineOUT => \$.);
- jsodump(protoName => "sandwich",
- dataRef => \%lunch,
- lineIN => $.);
-
- =item C<listObjects>
-
- A scalar, if true the parameters value is used as the name of an array to
- be output which will contain a list of all the dumped object.
- This allows data-ignorant client side code which need only
- traverse the named array.
-
- jsodump(protoName => "sandwich",
- dataRef => \@lunch,
- listObjects=> "sandwiches");
-
- would append the following to the output
-
- sandwiches = new Array('BLT', 'PBnJ');
-
- =back
-
- =head1 BUGS
-
- Nothing that am I aware of.
-
- =head1 SEE ALSO
-
- L<Data::JavaScript>, L<Data::Dumper>
-
- =head1 AUTHOR
-
- Jerrad Pierce I<jpierce@cpan.org>, I<webmaster@pthbb.org>.
- F<http://pthbb.org/>
-
- =cut
-