.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "JE::Types 3pm" .TH JE::Types 3pm "2021-01-08" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" JE::Types \- JavaScript types and objects .PP This is just documentation, not a module. .SH "DESCRIPTION" .IX Header "DESCRIPTION" The various JavaScript types and objects are represented by Perl classes in \s-1JE\s0 (which are listed below). This document describes the basic interface implemented by these classes. Information specific to each class can be found on its own manual page. .SH "UPGRADING VALUES" .IX Header "UPGRADING VALUES" When a value is passed from Perl to JavaScript, it will be \*(L"upgraded\*(R" to a Perl object representing a JavaScript value. This is done by the \f(CW\*(C`upgrade\*(C'\fR method of the global object. .PP If the value to be upgraded is a blessed reference, and the class into which it is blessed has been bound using \s-1JE\s0's \f(CW\*(C`bind_class\*(C'\fR method, it is wrapped up in a proxy object that provides the methods \s-1JS\s0 needs. A blessed reference whose class has not been bound will be left alone (we assume you know what you are doing). Otherwise the conversion is as follows: .PP .Vb 8 \& From To \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& undef undefined \& array ref Array \& hash ref Object \& code ref Function \& \*(Aq0\*(Aq number \& other scalar string .Ve .PP \&\fB\s-1WARNING:\s0\fR The 'upgrading' of simple scalars (strings/numbers) and regexps is still subject to change. .PP \&\fBTo do:\fR Make &JE::upgrade detect whether a simple scalar is a string or number. .PP \&\fBTo do:\fR Convert Regexp objects to JE::Object::RegExp objects. .SH "WHICH CLASSES ARE WHICH" .IX Header "WHICH CLASSES ARE WHICH" Each built-in JavaScript class or primitive type is a Perl class underneath. Here is the complete list of object classes: .PP .Vb 10 \& JavaScript Perl \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Object JE::Object \& Function JE::Object::Function \& Array JE::Object::Array \& String JE::Object::String \& Boolean JE::Object::Boolean \& Number JE::Object::Number \& Date JE::Object::Date \& RegExp JE::Object::RegExp \& Error JE::Object::Error \& RangeError JE::Object::Error::RangeError \& ReferenceError JE::Object::Error::ReferenceError \& SyntaxError JE::Object::Error::SyntaxError \& TypeError JE::Object::Error::TypeError \& URIError JE::Object::Error::URIError .Ve .PP And here are the primitive types: .PP .Vb 5 \& string JE::String \& number JE::Number \& boolean JE::Boolean \& null JE::Null \& undefined JE::Undefined .Ve .PP And I might also mention a few special cases: .PP .Vb 5 \& Global JE \& Math JE::Object::Math \& Arguments JE::Object::Function::Arguments \& Function scope JE::Object::Function::Call \& RegExp constructor JE::Object::Function::RegExpConstructor .Ve .PP The last three are for internal use. .SH "PUBLIC API" .IX Header "PUBLIC API" .SS "Using \s-1JS\s0 Values as Scalars" .IX Subsection "Using JS Values as Scalars" Every \s-1JS\s0 data type can be used as a string, boolean or number. It works exactly as it does in JavaScript. For example: .PP .Vb 5 \& $num = $je\->eval(\*(Aq42\*(Aq); \& $num2 = $je\->eval(\*(AqNaN\*(Aq); \& print $num2; # prints NaN \& print 0+$num2; # prints nan or NaN, depending or your system \& # (or something really weird on Windows). \& \& $zero_str = $je\->eval("\*(Aq0\*(Aq"); \& print "true" if $zero_str; # prints \*(Aqtrue\*(Aq \& print "false" unless 0+$zero_str; # prints \*(Aqfalse\*(Aq \& \& $false = $je\->eval(\*(Aqfalse\*(Aq); \& print $false; # prints \*(Aqfalse\*(Aq \& print "false" unless $false; # also prints \*(Aqfalse\*(Aq .Ve .SS "Property Access" .IX Subsection "Property Access" To access the property of a \s-1JS\s0 object, or of the \&\s-1JS\s0 environment itself (i.e., a global variable), just use it as a hash ref: .PP .Vb 4 \& $je\->{String}; # gives you the String constructor function \& $je\->{undefined}; # the undefined value \& my $obj = $je\->eval(\*(Aqvar obj = new Object; return obj\*(Aq); \& $obj\->{foo} = \*(Aqbar\*(Aq; .Ve .PP \&\f(CW\*(C`keys\*(C'\fR will return a list of the object's enumerable properties, including those inherited from its prototype. The following example prints \&'baz foo ': .PP .Vb 2 \& $obj = $je\->eval(\*(AqObject.prototype.foo="bar"; ({baz:43}) \*(Aq); \& print "$_ " for keys %$obj; .Ve .PP \&\f(CW\*(C`exists\*(C'\fR and \f(CW\*(C`delete\*(C'\fR act upon properties of the object itself, ignoring those of its prototype, so \f(CW\*(C`exists $obj\->{foo}\*(C'\fR will return false. .SS "Calling Methods" .IX Subsection "Calling Methods" To call a method on an object or primitive data type, use the \f(CW\*(C`method\*(C'\fR method: .PP .Vb 2 \& my $number = $je\->eval(\*(Aq42\*(Aq); \& $number\->method(\*(AqtoString\*(Aq, 16); # returns the number in hexadecimal .Ve .SS "Calling Functions" .IX Subsection "Calling Functions" Just use a function as though it were a coderef: .PP .Vb 1 \& $je\->{Array}\->(); .Ve .PP If you need to specify the invocant ('this' value), use the \f(CW\*(C`call_with\*(C'\fR method: .PP .Vb 1 \& $je\->{Number}{prototype}{toString}\->call_with($je\->eval(\*(Aq42\*(Aq), 16); .Ve .SS "Just Getting a Simple Perl Scalar" .IX Subsection "Just Getting a Simple Perl Scalar" To convert one of the fancy objects returned by \s-1JE\s0 into a simple Perl value, use the \f(CW\*(C`value\*(C'\fR method. .PP .Vb 4 \& $number\->value; # simple Perl scalar \& $str\->value; # likewise \& $obj\->value; # hash ref \& $array\->value; # array ref .Ve .PP Currently the \f(CW\*(C`value\*(C'\fR method of objects and arrays is not recursive, but I plan to make it so later on. The only way to get consistent behaviour between this and future versions is to pass \f(CW\*(C`recursive => 0\*(C'\fR as arguments. .SH "DATA TYPE API (in more detail)" .IX Header "DATA TYPE API (in more detail)" If you are going to write your own custom data types, proxy objects, or subclasses of \s-1JE\s0's classes, you'll need to read this. If not, you shouldn't need to, but you might like to anyway. :\-) .PP Be warned that some of the methods described here can be hard to use, and can easily result in code that's hard to debug, if misused. This applies to those that expect their arguments already to be objects compatible with the JE::Types interface. If you are not sure that a value you have is such, run it through the global object's \f(CW\*(C`upgrade\*(C'\fR method (or just use the \*(L"\s-1PUBLIC API\*(R"\s0, above). .PP These are the methods that the JavaScript engine itself uses (as opposed to those provided for convenient access from the Perl side). Each class provides whichever of the following methods are applicable. If an object does not support a particular method, a TypeError will be thrown when JavaScript code (indirectly) tries to call that method. (For instance, \&\f(CW\*(C`\*(Aqsome_string\*(Aq()\*(C'\fR will attempt to call the \f(CW\*(C`call\*(C'\fR method of JE::String, thus resulting in a TypeError). .IP "prop($name)" 4 .IX Item "prop($name)" .PD 0 .ie n .IP "prop($name, $new_value)" 4 .el .IP "prop($name, \f(CW$new_value\fR)" 4 .IX Item "prop($name, $new_value)" .PD Gets or sets a property. Setting a property returns the new value. The return value will be a Perl undef if the property does not exist. See also JE::Object, for the \&\f(CW\*(C`prop({ ... })\*(C'\fR usage. .Sp The new value is expected already to be an object compatible with the JE::Types interface. .IP "keys" 4 .IX Item "keys" Returns a list of the names of enumerable properties. This is a list of Perl strings, not JE::Strings. .IP "delete($name)" 4 .IX Item "delete($name)" Deletes the property named \f(CW$name\fR, if it is deletable. If the property did not exist or it was deletable, then true is returned. If the property exists and could not be deleted, false is returned. .Sp JE::Object will also take a second argument, that allows one to indicate whether an undeletable property should be deleted. This is required by custom classes if the object in question is the global object. .Sp The return value is a Perl scalar, not a JE::Boolean. .IP "value" 4 .IX Item "value" This returns a value that is supposed to be useful in Perl. The \&\f(CW\*(C`value\*(C'\fR method of a JE::Object::Array, for instance, produces an array ref. .IP "call(@args)" 4 .IX Item "call(@args)" Runs the code associated with the object if it is a function. The arguments are passed as-is, and are not upgraded. .ie n .IP "apply($obj, @args)" 4 .el .IP "apply($obj, \f(CW@args\fR)" 4 .IX Item "apply($obj, @args)" Runs the code associated with the object if it is a function. \f(CW$obj\fR will be passed to the function as its invocant (its 'this' value). The arguments are passed, as-is, and are not upgraded. .IP "construct(@args)" 4 .IX Item "construct(@args)" This is just like calling a function in \s-1JS\s0 with the \f(CW\*(C`new\*(C'\fR keyword (which itself calls this method). It calls the constructor, if this function has one (functions written in \s-1JS\s0 don't have this). Otherwise, an empty object will be created and passed to the function as its invocant. The return value of the function will be returned if it is an object. Otherwise it will be discarded, and the object originally passed to the function will be returned instead (possibly modified). .IP "exists($property_name)" 4 .IX Item "exists($property_name)" Returns a boolean indicating whether the property exists and is not inherited from a prototype. Used by \&\f(CW\*(C`Object.prototype.hasOwnProperty\*(C'\fR. (The \f(CW\*(C`in\*(C'\fR operator checks to see whether the return value of \f(CW\*(C`prop\*(C'\fR is defined.) .Sp \&\fBTo do:\fR Implement this method in subclasses of JE::Object. .IP "is_readonly($property_name)" 4 .IX Item "is_readonly($property_name)" Not supported by the primitive \s-1JE\s0 classes. This returns a boolean indicating whether a given property is readonly. If it doesn't exist, then the \f(CW\*(C`is_readonly\*(C'\fR method of the object's prototype is called with the same arguments. If there is no prototype, false is returned. This is used internally by JE::Object's \f(CW\*(C`prop\*(C'\fR method. .IP "is_enum($property_name)" 4 .IX Item "is_enum($property_name)" Not supported (yet) by the primitive \s-1JE\s0 classes. This returns a boolean indicating whether a given property is enumerable. This is used by \f(CW\*(C`Object.prototype.propertyIsEnumerable\*(C'\fR. .IP "typeof" 4 .IX Item "typeof" Returns a Perl string containing the type of the object. Used by the \s-1JS\s0 \f(CW\*(C`typeof\*(C'\fR operator. .IP "class" 4 .IX Item "class" This applies to object classes only (though it is going to change, so that primitives can pretend to be objects). It returns a Perl string containing the type of object. This is only used by the default JavaScript \&\f(CW\*(C`toString\*(C'\fR method. If you create your own object class without subclassing JE::Object, you should \fIstill\fR provide the \f(CW\*(C`class\*(C'\fR method, so that this \&\s-1JS\s0 code will still work: .Sp .Vb 2 \& YourClass.prototype.toString = Object.prototype.toString; \& (new YourClass).toString(); .Ve .IP "id" 4 .IX Item "id" This returns a unique id for the object or primitive, used by the JavaScript \f(CW\*(C`===\*(C'\fR operator. This id is unique as a \fIstring,\fR not as a number. .Sp The \s-1JE\s0 primitive classes provide a unique string beginning with the data type. The JE::Object and its subclasses return the memory address of the object itself. If you subclass JE::Object, you should not have to implement this method, unless you have multiple objects that you would like \s-1JS\s0 to consider the same object. .Sp Note that the id 'num:nan' is treated specially. It is never considered equal to itself. .IP "primitive" 4 .IX Item "primitive" Returns true or false. .IP "prototype" 4 .IX Item "prototype" .PD 0 .ie n .IP "prototype ( $obj )" 4 .el .IP "prototype ( \f(CW$obj\fR )" 4 .IX Item "prototype ( $obj )" .PD This applies to objects only, not to primitives. This method returns the prototype of the object, or undef if there is no prototype. If \f(CW$obj\fR is specified, the prototype is set to that object first. The \f(CW\*(C`prop\*(C'\fR method uses this method, as does \f(CW\*(C`JE::Object\->new\*(C'\fR. .IP "to_primitive($preferred_type)" 4 .IX Item "to_primitive($preferred_type)" .PD 0 .IP "to_boolean" 4 .IX Item "to_boolean" .IP "to_string" 4 .IX Item "to_string" .IP "to_number" 4 .IX Item "to_number" .IP "to_object" 4 .IX Item "to_object" .PD These each perform the appropriate type conversion. \f(CW$preferred_type\fR, which is optional, must be either 'string' or 'number'. .Sp Calling \f(CW\*(C`to_string\*(C'\fR or \f(CW\*(C`to_number\*(C'\fR on a object is not exactly the same as calling \&\f(CW\*(C`to_primitive(\*(Aqstring\*(Aq)\*(C'\fR or \f(CW\*(C`to_primitive(\*(Aqnumber\*(Aq)\*(C'\fR, because the argument to \f(CW\*(C`to_primitive\*(C'\fR is merely a \fIsuggestion.\fR .Sp The last four methods in this list should not be overridden by subclasses of JE::Object. .IP "global" 4 .IX Item "global" Returns a reference to the global object. .IP "taint($taint_brush)" 4 .IX Item "taint($taint_brush)" This will only be called if it is implemented. Of \s-1JE\s0's types, only primitive strings and numbers implement this. .Sp \&\f(CW$taint_brush\fR will always be a tainted empty string. If the object's internal value is not tainted, this method should return a tainted clone of the object. Otherwise, it should return the object itself. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\s-1JE\s0 and all the modules listed above under \*(L"\s-1WHICH CLASSES ARE WHICH\*(R"\s0.