home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / LiteObject.pm < prev    next >
Encoding:
Perl POD Document  |  2002-08-02  |  6.4 KB  |  248 lines

  1. package Data::JavaScript::LiteObject;
  2. use strict;
  3. use vars qw($VERSION $JSVER);
  4. $VERSION = '1.04';
  5.  
  6. sub import{
  7.   no strict 'refs';
  8.   shift;
  9.   $JSVER = shift || 1.0;
  10.   *{"@{[scalar caller()]}::jsodump"} = \&jsodump;
  11. }
  12.  
  13. sub jsodump {
  14.   my %opts = @_;
  15.   my(@keys, $obj, @objs, $EOL, $EOI, @F);
  16.  
  17.   unless( $opts{protoName} && $opts{dataRef} ){
  18.     return warn("// Both protoName and dataRef must be supplied");
  19.   }
  20.  
  21.   ($EOI, $EOL) = $opts{explode} ? ("$/\t")x2 : ('', ' ');
  22.  
  23.   if( ref($opts{dataRef}) eq "ARRAY" ){
  24.     my $i=0;
  25.     $opts{dataRef} =  {map {$opts{protoName}.$i++=>$_} @{$opts{dataRef}} };
  26.   }
  27.   #NOT elsif
  28.   if( ref($opts{dataRef}) eq "HASH" ){
  29.     if( ref($opts{attributes}) eq "ARRAY" ){
  30.       @keys = @{$opts{attributes}};
  31.     }
  32.     else{
  33.       @keys = sort { $a cmp $b } keys
  34.     %{$opts{dataRef}->{(sort keys %{$opts{dataRef}})[0]}};
  35.     }
  36.   }
  37.   else{
  38.     warn("// Unknown reference type, attributes"); return;
  39.   }
  40.  
  41.   push @F, "function $opts{protoName} (", join(', ', @keys) ,") {$/\t";
  42.   push @F, map("this.$_ = $_;$EOL", @keys);  
  43.   push @F, "}$/";
  44.  
  45.   foreach $obj ( sort keys %{$opts{dataRef}} ){
  46.     push @F, "$obj = new $opts{protoName}($EOI";
  47.     push @F, join(",$EOL",
  48.           map(datum($opts{dataRef}->{$obj}->{$_}), @keys) ).$EOL;
  49.     push @F, ");$/";
  50.     push @objs, $obj;
  51.   }
  52.  
  53.   if( defined($opts{listObjects}) ){
  54.     push @F, "$opts{listObjects} = new Array($EOI",
  55.       join(",$EOL", map("'$_'", @objs)), ");$/";
  56.   }
  57.  
  58.   if( defined($opts{lineIN}) ){
  59.     local $. = $opts{lineIN}+1;
  60.     @F = split($/, join('', @F));
  61.     foreach ( @F ) {
  62.       $_ .= $/ . '// '. ++$. unless (++$.-$opts{lineIN}) %5;
  63.       $_ .= $/;
  64.     }
  65.     ${$opts{lineOUT}} = $.;
  66.     unshift @F, '// '. ($opts{lineIN}+1) .$/;
  67.   }
  68.   return @F;
  69. }
  70.  
  71. sub datum {
  72.   local $_ = shift() || '';
  73.   my $val;
  74.  
  75.   if ( ref eq "ARRAY" ) {
  76.     $val = $JSVER >= 1.2 ?
  77.       "[" . join(',',
  78.          map /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ ?
  79.          $_ : do{ s/'/\\'/g; qq('$_') }, @{$_})
  80.     . "]"
  81.     :
  82.  
  83.       "new Array(" . join(',',
  84.               map /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ ?
  85.               $_ : do{ s/'/\\'/g; qq('$_') }, @{$_})
  86.     . ")";
  87.  
  88.   }
  89.   elsif( $val = $_, $val !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ ){
  90.     s/'/\\'/g;
  91.     $val = qq('$_');
  92.   }
  93.  
  94.   return $val;
  95. }
  96.  
  97. 1;
  98. __END__
  99.  
  100. =pod
  101.  
  102. =head1 NAME
  103.  
  104. Data::JavaScript::LiteObject - lightweight data dumping to JavaScript
  105.  
  106. =head1 SYNOPSIS
  107.  
  108.     use Data::JavaScript:LiteObject;
  109.     #OR
  110.     use Data::JavaScript:LiteObject '1.2';
  111.  
  112.     %A = (protein      => 'bacon',
  113.           condiments   => 'mayonaise',
  114.           produce      => [qw(lettuce tomato)]);
  115.     %B = (protein      => 'peanut butter',
  116.           condiments   => 'jelly');
  117.     @lunch             = (\%A, \%B);
  118.     %lunch             = (BLT=>\%A, PBnJ=>\%B);
  119.  
  120.     jsodump(protoName  => "sandwich",
  121.             dataRef    => \%lunch
  122.             attributes => [qw(condiments protein produce)]);
  123.  
  124. =head1 DESCRIPTION
  125.  
  126. This module was inspired by L<Data::JavaScript>, which while incredibly
  127. versatile, seems rather brute force and inelegant for certain forms
  128. of data. Specifically a series of objects of the same class, which it
  129. seems is a likely use for this kind of feature. So this module was
  130. created to provide a lightweight means of producing configurable, clean
  131. and compact output.
  132.  
  133. B<LiteObject> is used to format and output loh, hoh, lohol, and hohol.
  134. The output is JavaScript 1.0 compatible, with the limitation that none
  135. of the properties be a single-element array whose value is a number.
  136. To lift this limitation pass use the extra value I<'1.2'>, which will
  137. generate JavaScript 1.2 compatible output.
  138.  
  139. One function, B<jsodump>, is exported. B<jsodump> accepts a list of named
  140. parameters; two of these are required and the rest are optional.
  141.  
  142. =head2 Required parameters
  143.  
  144. =over 4
  145.  
  146. =item C<protoName>
  147.  
  148. The name to be used for the prototype object function.
  149.  
  150. =item C<dataRef>
  151.  
  152. A reference to an array of hashes(loh) or hash of hashes(hoh) to dump.
  153.  
  154. =back
  155.  
  156. =head2 Optional parameters
  157.  
  158. =over 4
  159.  
  160. =item C<attributes>
  161.  
  162. A reference to an array containing a list of the object attributes
  163. (hash keys). This is useful if every object is not guaranteed to
  164. posses a value for each attribute.
  165. It could also be used to exclude data from being dumped.
  166.  
  167. =item C<explode>
  168.  
  169. A scalar, if true output is one I<attribute> per line.
  170. The default; false; is one I<object> per line.
  171.  
  172. =item C<lineIN>
  173.  
  174. A scalar, if true output is numbered every 5 lines. The value provided
  175. should be the number of lines printed before this output.
  176. For example if a CGI script included:
  177.  
  178.     print q(<html>
  179.         <head>
  180.         <title>Pthbb!!</title>
  181.         <script language=javascript>);>
  182.     jsodump(protoName  => "sandwich",
  183.             dataRef    => \@lunch,
  184.             lineIN     => 4);
  185.  
  186. The client would see:
  187.  
  188.     <html>
  189.     <head>
  190.     <title>Pthbb!!</title>
  191.     <script language=javascript>
  192.     // 5
  193.     function sandwich (condiment, produce, protein) {
  194.             this.condiment = condiment; this.produce = produce; this.protein = protein; }
  195.     BLT = new sandwich('mayonaise', new Array('lettuce','tomato'), 'bacon' );
  196.     PBnJ = new sandwich('jelly', '', 'peanut butter' );
  197.     // 10
  198.  
  199. making it easier to read and/or debug.
  200.  
  201. =item C<lineOUT>
  202.  
  203. A reference to a scalar. B<jsodump> will set the scalar's value to the number
  204. of the last line of numbered output produced when lineIN is specified. Thus
  205. you may pass the scalar to a subsequent call to B<jsodump> as the value of
  206. lineIn for continuous numbering.
  207. For example:
  208.  
  209.     jsodump(protoName  => "sandwich",
  210.               dataRef  => \@lunch,
  211.               lineIN   => 4,
  212.               lineOUT  => \$.);
  213.     jsodump(protoName  => "sandwich",
  214.               dataRef  => \%lunch,
  215.               lineIN   => $.);
  216.  
  217. =item C<listObjects>
  218.  
  219. A scalar, if true the parameters value is used as the name of an array to
  220. be output which will contain a list of all the dumped object.
  221. This allows data-ignorant client side code which need only
  222. traverse the named array.
  223.  
  224.     jsodump(protoName  => "sandwich",
  225.             dataRef    => \@lunch,
  226.             listObjects=> "sandwiches");
  227.  
  228. would append the following to the output
  229.  
  230.     sandwiches = new Array('BLT', 'PBnJ');
  231.  
  232. =back
  233.  
  234. =head1 BUGS
  235.  
  236. Nothing that am I aware of.
  237.  
  238. =head1 SEE ALSO
  239.  
  240. L<Data::JavaScript>, L<Data::Dumper>
  241.  
  242. =head1 AUTHOR
  243.  
  244. Jerrad Pierce I<jpierce@cpan.org>, I<webmaster@pthbb.org>.
  245. F<http://pthbb.org/>
  246.  
  247. =cut
  248.