NAME

JavaScript - Perl extension for executing embedded JavaScript

SYNOPSIS

    #!/usr/bin/perl
  
    use JavaScript;

    my $runtime = new JavaScript::Runtime;
    my $context = $runtime->create_context();

    $context->bind_function( name => 'write', func => sub { print @_ } );

    $rval = $context->eval(q!
      function strange(out, times) {
        times = Math.abs(times);
        for(i = 0; i < times; i++) {
          write(out);
        }
      }

      strange("JavaScript.pm rox!", 10);

      undefined;
    !);

DESCRIPTION

Always thought JavaScript was for web only? well, think again...

JavaScript.pm gives you the power of embedded JavaScript in your applications. You can write your subs, classes etc in perl and bind them to the JavaScript engine. Variables are converted between the language automaticlly and you don't have to worry about that.

Why?

JavaScript is safe. It has no I/O, no IPC and pretty much nothing else except that's it is an easy language that zillions of developers worldwide knows.

How?

This is not a JavaScript runtime written in perl, it's simply an interface to libjs from the mozilla crew.

INSTALL

See README file for more information on installation

REFERENCE

Some regulations applies to certain values that are passed to the methods. JavaScript identifiers (ie, function names, method names, objects names) must only contain A-Z, a-z, 0-9 and _

JavaScript

Importing the module:

use JavaScript qw(:all);

Constants exported:

JS_PROP_PRIVATE

Sets that an objects property can't be accessed from JavaScript

JS_PROP_READONLY

Sets that an objects property can't be set from JavaScript

JS_CLASS_NO_INSTANCE

Sets that instances of this class can't be created from JavaScript

JavaScript::Runtime

Contexts used by your application are maintained in runtimes. So before you can do anything, create a new JavaScript::Runtime object.

Methods:

JavaScript::Runtime = new JavaScript::Runtime($maxbytes)

Creates a new JavaScript::Runtime object under which you can create multiple contexts.

$maxbytes specifies the number of bytes it can allocate before garbage collection is done. 1 MB is used as default.

------

JavaScript::Context = JavaScript::Runtime->create_context($stacksize)

Creates and returns a new JavaScript::Context object in which you can bind classes and functions, evalutate scripts, call JS function and bind perl objects.

$stacksize specifies the the number of bytes to allocate for the stack.

JavaScript::Context

All execution of JavaScript is done in a context.

Methods:

SCALAR = JavaScript::Context->eval($code);

Compiles and evaluates JS code supplied in $code. Returns the the value of the last JS statement.

Example:

 $rval = $context->eval(q!
   a = 10;
   b = 20;
   c = a * b;
   c;
 !);

-----

SCALAR = JavaScript::Context->eval_file($path)

Compiles and evaulates JS code in the file with the path in $path. Returns the value of the last JS statement.

-----

SCALAR = JavaScript::Context->call($func, ...);

Calls a JS function with name in $func. Rest of parameters are passed to the JS function.

Example:

 $context->eval(q!
   function multiply(a, b) {
     return a, b;
   }
 !);

 $ret = $context->call("multiply", 10, 20);

-----

SCALAR = JavaScript::Context->can($func)

Returns a true value if there is a function named $func in the context. Otherwize, it returns false.

Example:

 if($context->can('on_update')) {
   $context->call('on_update', $page);
 }

-----

JavaScript::Context->bind_function( name => $name, func => $sub )

The bind_function method binds a perl function to the JS namespace. The argument 'name' must only contain A-Z, a-z, 0-9 and _. Argument 'func' is a reference to a subroutine.

Example:

 $context->bind_function(
   name => 'writeln', 
   func => sub { print @_ . "\n"; }
 );

-----

JavaScript::Context->bind_class( name => $name, constr => $sub [,methods => { ... }, properties => { ... }, package => $pkg, flags => $flags ]);

Creates a new JS Class in the context, which is actually implemented in perl. Argument name is the name of the new class which can be use in JS using "var obj = new Foo()". Argument constructor must be a code reference which is called when the instance is created (note, does not send package as first argument so sub { return new Foo(@_) } is recommended). Argument methods is a hash reference where each key is the name of the method and the value is a code reference to the native method to call. Argument properties is a hash reference containing names of properties and how they can are treated (See constants exported by JavaScript package), these can be OR'd. Argument flags contains flags for this class, only supported now is JS_CLASS_NO_INSTANCE if this class can't be instanciated. Argument package is the name of the perl package this class represents, must be supplied if you want to be able to sent objects when using call.

Example:

 $context->bind_class(
   name => 'Foo', 
   constructor => sub { return new Foo(@_); }, 
   methods => { 
     bar => \&Foo::bar, 
     baz => \&Foo::baz, }, 
   package => 'Foo'
 ); 

 $context->eval(q!
   var obj => new Foo();
   obj.bar("Hello World");
   obj.baz("Bye Bye World");
   obj = undefined;
 !);

 $context->eval(q!
   function func(obj) { 
     obj.bar("No World"); 
   }!
 );
 
 $context->call("func", new Foo());

-----

JavaScript::Context->bind_object($name, $object);

Creates a new JS object in the context with the name supplied in $name. It checks what $object is blessed to an uses that to determine the type of JS class it represents. The class must be bound before importion can occur and the package argument must be supplied.

Example:

 $context->bind_class(
   name => 'Response', 
   constr => sub { return new Response(); }, 
   methods => { write => \&Response::write },
   flags => JS_CLASS_NO_INSTANCE 
 );

 my $stdout = new Response("STDOUT");
 my $stderr = new Response("STDERR");

 $context->bind_object('Stdout', $stdout);
 $context->bind_object('Stderr', $stderr);

 $context->eval(q!
   Stdout.write("Hello World\n");
   Stderr.write("Bye Bye world\n");
 !);

-----

JavaScript::Script = JavaScript::Context->compile($code);

Compiles a piece of code and returns a new JavaScript::Script object containing the precompiled script.

------

NOT YET 100% IMPLEMENTED!

JavaScript::Context->set_error_handler($sub);

Sets the error callback in the context to be the subruntine referenced by $sub. The subrutine wil be passed the following arguments in this order:

 message - The error in plaintext
 line number - On which line number the error occured
 line buffer - The line in plaintext on which the error occured

Example:

 $context->set_error_handler(sub {
   my ($message, $lineno, $linebuff) = @_;

   die "Error at line: $lino\nMessage is: $message\nSource is: $linebuff\n";
 });


 $context->eval(q!
  for(i = ; i <40; i+++) {
  }
 !);

JavaScript::Script

Precompiled scripts goes here. Once a script is compiled, it can be run over and over again.

Methods:

SCALAR = JavaScript::Script->exec();

Executes the precompiled script an returns the result of the last statement in it.

SUPPORT

Mailing list

JavaScript.pm has a mailing list at perl.org.

You may subscribe by sending an empty email to perl-javascript-subscribe@perl.org (NOTE!! this is currently not working)

Website

JavaScript.pm has a website at http://labs.contiller.se/JavaScript/

IRC

Channel #javascript.pm on irc.infobot.org

THANKS

Mozilla Crew and Netscape for excellent SpiderMonkey JS engine.

#perl on irc.infobot.org for feedback and help.

BUGS

Doesn't handle memory issues very well atm.

AUTHOR

Claes Jacobsson, Contiller AB, claes@contiller.se

COPYRIGHT

JavaScript.pm is Copyright 2001 Claes Jacobsson, Contiller AB. All right reserved.

JavaScript.pm is free software; you may redistribute it and/or modify it under the same terms as Perl itself.