JE::Ob...nction(3pm)

πŸ“¦
version 0.066 Β· 3 versions
, in debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

✨ NAME ✨

JE::Object::Function β€” the JavaScript function class, bestie πŸ’– (from the User Contributed Perl Documentation, if you were wondering where we're at)


πŸŽ€ SYNOPSIS πŸŽ€

use JE::Object::Function;

# simple constructors:

$f = new JE::Object::Function $scope, @argnames, $function;
$f = new JE::Object::Function $scope, $function;

# constructor that lets you do anything:

$f = new JE::Object::Function {
        name             => $name,
        scope            => $scope,
        length           => $number_of_args,
        argnames         => [ @argnames ],
        function         => $function,
        function_args    => [ $arglist ],
        constructor      => sub { ... },
        constructor_args => [ $arglist ],
        downgrade        => 0,
};

$f->(@args);
$f->call_with($obj, @args);

πŸ’… DESCRIPTION πŸ’…

okay so every single JavaScript function out there? it's an instance of this class. that's the whole vibe. all of them ✨

and if you wanna call a JS function from Perl, you literally just treat it like a coderef ($f->()) 🫢 or, if you need to pick who the invocant is (aka the this value), you use the call_with method instead: $f->call_with($obj, @args). iconic behaviour, no cap πŸ’œ


🌸 OBJECT CREATION 🌸

new

Creates and returns a brand new function (peep the next few items for how you actually use it). The new function comes with a prototype property, and that prototype is an object with a constructor property pointing right back at the function itself. it's giving self-referential queen πŸ‘‘

The return value of the function gets upgraded if necessary (go read UPGRADING VALUES in the JE::Types man page for that tea πŸ“) β€” and that is literally why new has to be handed a reference to the global object or the scope chain. (But also go look at new_function in JE and new_method in JE, they're relevant too.)

A function written in Perl is allowed to return an lvalue if it wants to. Use new JE::LValue($object, 'property name') to make one. And if you want an lvalue that refers to a variable visible inside the function's scope, use $scope->var('varname') β€” this assumes you've shifted the scope object off @_ and named it $scope, and you also gotta call new with the hashref syntax and specify function_args (see below for that one).

new JE::Object::Function $scope_or_global, @argnames, $function;

new JE::Object::Function $scope_or_global, $function;

So $scope_or_global is one of these two things:

  • a global (JE) object
  • a scope chain (JE::Scope) object

@argnames is the list of argument names β€” the ones JavaScript functions use to get at their arguments.

And $function is one of:

  • a string containing the body of the function (JavaScript code)
  • a JE::Code object
  • a coderef

new JE::Object::Function { ... };

This is the big fancy way of creating a function that lets you do literally anything. The elements of the hash ref you pass to new are as follows (they're all optional, except for scope β€” that one is mandatory, periodt):

  • name β€” the name of the function. This is used only by toString. it's just for show, bestie πŸ’…
  • scope β€” a global object or scope chain object.
  • length β€” the number of arguments expected. If you omit it, the number of elements in argnames gets used instead. If you omit that too, then 0 is used. Quick heads up tho: this does not make the argument list get checked. It only provides the length property (and possibly, later on, an arity property) for inquisitive scripts to peek at πŸ‘€
  • argnames β€” an array ref holding the variable names that a JS function uses to access the arguments.
  • function β€” a coderef, a string of JS code, or a JE::Code object (this is the body of the function).

This gets run when the function is called from JavaScript without the new keyword, or from Perl via the call method.

  • function_args β€” this only applies when function is a code ref. function_args is an array ref, and its elements are strings that say what arguments should be passed to the Perl subroutine. Here are the strings and what they mean:
self    the function object itself
scope   the scope chain
global  the global object
this    the invocant
args    the arguments passed to the function (as individual
        arguments)
[args]  the arguments passed to the function (as an array ref)

If function_args is omitted, 'args' will be assumed.

  • constructor β€” a code ref that creates and initialises a new object. This gets called when the new keyword is used in JavaScript, or when the construct method is used in Perl.

If you omit this, then when new or construct is used, a new empty object gets created and passed to the sub specified under function as its this value. The return value of the sub gets returned if it's an object; otherwise the (possibly modified) object that was originally passed to the function gets returned instead.

  • constructor_args β€” like function_args, but the 'this' string does not apply. If constructor_args is omitted, the arg list will be set to [ qw( scope args ) ] (this might change πŸ‘€).

This is completely ignored if constructor is omitted.

  • downgrade β€” (not yet implemented) β€” this applies only when function or constructor is a code ref. It's a boolean indicating whether the arguments to the function should have their value methods called automatically.; i.e., as though map $_->value, @args were used instead of @args.
  • no_proto β€” if this is set to true, the returned function will have no prototype property. bye bye prototype πŸ¦‹

πŸ”₯ METHODS πŸ”₯

new JE::Object::Function

See "OBJECT CREATION" above, bestie β€” it's all up there πŸ‘†

call_with ( $obj, @args )

Calls a function with the given arguments. $obj becomes the function's invocant. This method is meant for general use from the Perl side. The arguments (including $obj) are automatically upgraded. slay ✨

call ( @args )

This method β€” intended mainly for internal use β€” calls a function with the given arguments, without upgrading them. The invocant (the this value) will be the global object. It's just a wrapper around apply.

This method is very badly named and will probably be renamed in a future version. Does anyone have any suggestions? 😭

construct

This method, likewise intended mainly for internal use, calls the constructor β€” if this function even has one (functions written in JS don't have this). Otherwise, an object gets created and passed to the function as its invocant. The return value of the function gets discarded, and the object (possibly modified) gets returned instead. rip to that return value πŸ’€

apply ( $obj, @args )

This method, intended mainly for internal use just like the two above, calls the function with $obj as the invocant and @args as the args. No upgrading occurs.

This method is very badly named and will probably be renamed in a future version. Does anyone have any suggestions? πŸ™ˆ

typeof

This returns the string 'function'. as it should πŸ’…

class

This returns the string 'Function'.

value

Not yet implemented. soon tho? maybe? 🧚


πŸ’– OVERLOADING πŸ’–

You can use a JE::Object::Function as a coderef. The sub you get back simply invokes the call method, so these two lines are equivalent:

$function->call( $function->global->upgrade(@args) )
$function->(@args)

The stringification, numification, boolification, and hash dereference ops are also overloaded. Go see JE::Object, which this class inherits from. main character energy throughout πŸ‘‘


🌈 SEE ALSO 🌈

  • JE
  • JE::Object
  • JE::Types
  • JE::Scope
  • JE::LValue

and that's the whole page, bestie!! 🫢 this one's from perl v5.36.0, dated 2023-08-25 β€” go forth and construct some functions, you've absolutely got this πŸ’œβœ¨πŸŽ€

πŸ“¦ where this page comes from