JE::Types(3pm)
β¨ NAME β¨
okay so this is JE::Types β the JE::Types(3pm) page, bestie β and it's all about JavaScript types and objects. π
This is just documentation, not a module. π«Ά
π DESCRIPTION π
okay so JE is out here representing every JavaScript type and object with its own Perl class (full list below, don't worry). This doc is the vibe check for the basic interface these classes all implement. If you want the tea on a specific class, its own manual page has you covered. β¨
π¦ UPGRADING VALUES π¦
When a value slides from Perl over to JavaScript, it gets a glow-up β a.k.a. "upgraded" β into a Perl object that represents a JavaScript value. The global object's upgrade method is the one doing the makeover. π
If the value to be upgraded is a blessed reference, and the class into which it is blessed has been bound using JE's bind_class method, it is wrapped up in a proxy object that provides the methods JS 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:
From β To:
undefβundefinedarray refβArrayhash refβObjectcode refβFunction'0'βnumberother scalarβstring
WARNING: The 'upgrading' of simple scalars (strings/numbers) and regexps is still subject to change. β οΈ
To do: Make &JE::upgrade detect whether a simple scalar is a string or number.
To do: Convert Regexp objects to JE::Object::RegExp objects.
π 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, no cap:
JavaScript β Perl:
ObjectβJE::ObjectFunctionβJE::Object::FunctionArrayβJE::Object::ArrayStringβJE::Object::StringBooleanβJE::Object::BooleanNumberβJE::Object::NumberDateβJE::Object::DateRegExpβJE::Object::RegExpErrorβJE::Object::ErrorRangeErrorβJE::Object::Error::RangeErrorReferenceErrorβJE::Object::Error::ReferenceErrorSyntaxErrorβJE::Object::Error::SyntaxErrorTypeErrorβJE::Object::Error::TypeErrorURIErrorβJE::Object::Error::URIError
And here are the primitive types:
stringβJE::StringnumberβJE::NumberbooleanβJE::BooleannullβJE::NullundefinedβJE::Undefined
And I might also mention a few special cases:
GlobalβJEMathβJE::Object::MathArgumentsβJE::Object::Function::ArgumentsFunction scopeβJE::Object::Function::CallRegExp constructorβJE::Object::Function::RegExpConstructor
The last three are for internal use. π
π PUBLIC API π
β¨ Using JS Values as Scalars β¨
Every JS data type can flex as a string, boolean or number. It works exactly as it does in JavaScript. For example:
$num = $je->eval('42');
$num2 = $je->eval('NaN');
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("'0'");
print "true" if $zero_str; # prints 'true'
print "false" unless 0+$zero_str; # prints 'false'
$false = $je->eval('false');
print $false; # prints 'false'
print "false" unless $false; # also prints 'false'
π Property Access π
To access the property of a JS object, or of the JS environment itself (i.e., a global variable), just use it as a hash ref:
$je->{String}; # gives you the String constructor function
$je->{undefined}; # the undefined value
my $obj = $je->eval('var obj = new Object; return obj');
$obj->{foo} = 'bar';
keys will return a list of the object's enumerable properties, including those inherited from its prototype. The following example prints 'baz foo ':
$obj = $je->eval('Object.prototype.foo="bar"; ({baz:43}) ');
print "$_ " for keys %$obj;
exists and delete act upon properties of the object itself, ignoring those of its prototype, so exists $obj->{foo} will return false. π
π Calling Methods π
To call a method on an object or primitive data type, use the method method:
my $number = $je->eval('42');
$number->method('toString', 16); # returns the number in hexadecimal
πΈ Calling Functions πΈ
Just use a function as though it were a coderef:
$je->{Array}->();
If you need to specify the invocant ('this' value), use the call_with method:
$je->{Number}{prototype}{toString}->call_with($je->eval('42'), 16);
π§ Just Getting a Simple Perl Scalar π§
To convert one of the fancy objects returned by JE into a simple Perl value, use the value method.
$number->value; # simple Perl scalar
$str->value; # likewise
$obj->value; # hash ref
$array->value; # array ref
Currently the value 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 recursive => 0 as arguments. Lowkey important. β οΈ
𧬠DATA TYPE API (in more detail) π§¬
Okay bestie, listen. If you're gonna write your own custom data types, proxy objects, or subclasses of JE's classes, you need to read this. If not? You shouldn't need to. But you might like to anyway. :-)
β οΈ Heads up, gorgeous: some of the methods down here are hard to use, and if you misuse them you will end up with code that is genuinely a nightmare to debug. That goes double for the ones that expect their arguments already to be objects compatible with the JE::Types interface. Not sure if the value you're holding is one of those? Run it through the global object's upgrade method (or just use the PUBLIC API from up above, queen).
These are the methods that the JavaScript engine itself uses β not the ones provided for convenient access from the Perl side. Each class provides whichever of the following methods apply to it. If an object does not support a particular method, a TypeError gets thrown when JavaScript code (indirectly) tries to call that method. Like, for instance, 'some_string'() will attempt to call the call method of JE::String, and boom β TypeError. π
prop($name) / prop($name, $new_value)
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 prop({ ... }) usage. π
The new value is expected already to be an object compatible with the JE::Types interface.
keys
Returns a list of the names of enumerable properties. This is a list of Perl strings, not JE::Strings. (Yes, that matters. β¨)
delete($name)
Deletes the property named $name, 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.
JE::Object will also take a second argument, which lets you indicate whether an undeletable property should be deleted. Custom classes require this if the object in question is the global object.
The return value is a Perl scalar, not a JE::Boolean. Don't get it twisted.
value
This returns a value that is supposed to be useful in Perl. The value method of a JE::Object::Array, for instance, produces an array ref. π
call(@args)
Runs the code associated with the object, if it is a function. The arguments are passed as-is, and are not upgraded.
apply($obj, @args)
Runs the code associated with the object, if it is a function. $obj will be passed to the function as its invocant (its 'this' value). The arguments are passed as-is, and are not upgraded.
construct(@args)
This is just like calling a function in JS with the new keyword (which itself calls this method). It calls the constructor, if this function has one (functions written in JS 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). π
exists($property_name)
Returns a boolean indicating whether the property exists and is not inherited from a prototype. Used by Object.prototype.hasOwnProperty. (The in operator checks to see whether the return value of prop is defined.)
π To do: Implement this method in subclasses of JE::Object.
is_readonly($property_name)
Not supported by the primitive JE classes. This returns a boolean indicating whether a given property is readonly. If it doesn't exist, then the is_readonly 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 prop method.
is_enum($property_name)
Not supported (yet) by the primitive JE classes. This returns a boolean indicating whether a given property is enumerable. This is used by Object.prototype.propertyIsEnumerable.
typeof
Returns a Perl string containing the type of the object. Used by the JS typeof operator. π¦
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 toString method. If you create your own object class without subclassing JE::Object, you should still provide the class method, so that this JS code will still work:
YourClass.prototype.toString = Object.prototype.toString;
(new YourClass).toString();
id
This returns a unique id for the object or primitive, used by the JavaScript === operator. This id is unique as a string, not as a number.
The JE 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 JS to consider the same object.
πΈ Note that the id 'num:nan' is treated specially. It is never considered equal to itself.
primitive
Returns true or false. Simple as that. β¨
prototype / prototype ( $obj )
This applies to objects only, not to primitives. This method returns the prototype of the object, or undef if there is no prototype. If $obj is specified, the prototype is set to that object first. The prop method uses this method, as does JE::Object->new.
to_primitive($preferred_type) / to_boolean / to_string / to_number / to_object
These each perform the appropriate type conversion. $preferred_type, which is optional, must be either 'string' or 'number'.
Calling to_string or to_number on an object is not exactly the same as calling to_primitive('string') or to_primitive('number'), because the argument to to_primitive is merely a suggestion. π
π« The last four methods in this list should not be overridden by subclasses of JE::Object.
global
Returns a reference to the global object. π
taint($taint_brush)
This will only be called if it is implemented. Of JE's types, only primitive strings and numbers implement this.
$taint_brush 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.
π SEE ALSO π
JE, and all the modules listed above under "WHICH CLASSES ARE WHICH". Go read 'em, bestie, you got this. π«Ά
That's the whole page, and it came from perl v5.36.0, dated 2023-08-25 β shoutout to JE::Types(3pm), the manual page that ate and left no crumbs. πβ¨π
π¦ where this page comes from
- debian trixie: libje-perl 0.066-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libje-perl 0.066-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libje-perl 0.066-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libje-perl 0.066-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms