package Data::JavaScript::LiteObject; *{"@{[scalar caller()]}::jsodump"} = \&Data::JavaScript::LiteObject::jsodump; use strict; use vars qw($VERSION); $VERSION = '1.03'; 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 = "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; %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, 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 is used to format and output loh, hoh, lohol, and hohol. One function, B, is exported. B accepts a list of named parameters; two of these are required and the rest are optional. =head2 Required parameters =over 4 =item C The name to be used for the prototype object function. =item C A reference to an array of hashes(loh) or hash of hashes(hoh) to dump. =back =head2 Optional parameters =over 4 =item C 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 A scalar, if true output is one I per line. The default; false; is one I per line. =item C 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( Pthbb!!