Reply::Plugin(3pm)
π Reply::Plugin β the manual page, but make it cute π
okay bestie so this is Reply::Plugin(3pm), a page from the User Contributed Perl Documentation collection, and it's literally the blueprint for every Reply plugin that ever existed. it's giving β¨base classβ¨. it's giving "everything else inherits from me". periodt.
πΈ VERSION πΈ
version 0.42 β yes queen, we're on 0.42, write it down π
β¨ SYNOPSIS β¨
here's the vibe, copy-paste-able and everything:
package Reply::Plugin::Foo;
use strict;
use warnings;
use base 'Reply::Plugin';
# ...
that's it. that's the whole starter pack. you use base 'Reply::Plugin' and you're basically a plugin now π«Ά
π¦ DESCRIPTION π¦
so. a Reply plugin is an object that adds some functionality to a Reply instance by implementing specific methods that the Reply object will call at various points during execution. that's the whole deal. it's giving "callback girlie" energy, and honestly? iconic.
plugins may implement as many callback methods as they need to do their thing β but (and this is the tea β) the more callbacks a single plugin implements, the more likely it is that the plugin would lowkey be more useful split up into multiple independent plugins. just saying. modularity is the moment. π
now, callback methods have three potential calling conventions, and you gotta know which is which, fr fr:
- wrapped β wrapped callbacks get a coderef as their first argument, before any of the callback's own arguments. that coderef is how you call the next callback in the list (if more than one plugin implements a given callback). and bestie, this is the good part: it means you can call the next plugin multiple times, or not at all if you don't feel like it. wrapped plugins should always call their coderef in list context. and heads up β all plugins listed below are wrapped plugins unless it says otherwise. π
- chained β chained callbacks receive a list of arguments and return a new list of arguments which gets passed along to the next plugin in the chain. so every plugin gets a little moment to modify a value before the repl actually uses it. it's giving assembly line but make it slay. π
- concatenate β concatenate callbacks receive a list of arguments and return a list of response values. every plugin implementing that callback gets called with the same arguments, and all the results get concatenated together into one single list, which is what gets returned. callbacks for published messages are this type. π«
π CALLBACKS π
okay here's the full roster, no skipping, we don't do that here:
promptβ called to figure out what prompt to use when reading the next line. takes no arguments, returns a single string to use as the prompt. the default implementation returns">"π₯Ίread_lineβ called to actually read a line from the user. takes no arguments, returns a single string. the default implementation uses the"<>"operator to read a single line from"STDIN". classic. πcommand_$name(chained) β if the line read from the user looks like"#foo args...", then plugins get searched for a callback method named"command_foo". this callback takes a single string containing the arguments that were provided, and returns a new line to evaluate instead β if there is one. otherwise nothing. πͺmangle_line(chained) β modifies the line read from the user before it gets evaluated. takes the line as a string, returns the modified line. glow-up for your input. πcompileβ compiles the string of Perl code into a coderef. takes the line of code as a string and a hash of extra parameters, and returns the coderef to be executed. the default implementation uses Eval::Closure to compile the given string.
and the hash of extra parameters? it gets passed directly to "eval_closure". no middleman. π
executeβ executes the coderef that was just compiled. takes the coderef and a list of parameters to pass to it, and returns the list of results from calling the coderef. the default implementation just calls the coderef directly. simple. clean. iconic. β‘mangle_error(chained) β if the"compile"or"execute"callbacks throw an exception, this callback gets called to modify the exception before it's passed to"print_error". it receives the exception and returns the modified exception. π©Ήprint_errorβ if the"compile"or"execute"callbacks throw an exception, this callback gets called to display it to the user. it receives the exception and returns nothing. the default implementation just uses"print"to print it to the screen. πmangle_result(chained) β used to modify the result of evaluating the line of code before it gets displayed. receives the list of results, returns a modified list of results. β¨print_resultβ displays the results of evaluating the given line of code to the user. receives the list of results and returns nothing. the default implementation just uses"print"to print them to the screen. πΊloop(chained) β called at the end of every evaluation. it receives whether the repl has been requested to terminate so far, and returns whether the repl should terminate. π
Reply plugins can also talk to each other through a pub/sub mechanism π. by calling the "publish" method, every plugin that responds to the given message (aka implements a method with that name) will have that method called with the given arguments, and all the responses get collected and returned. some messages used by the default plugins are:
tab_handler ($line)β plugins can publish this message when they want to attempt tab completion. plugins that respond to it should return a list of potential completions of the line that got passed in. ποΈlexical_environmentβ plugins that want to modify the lexical environment should do it by implementing this message, which should return a hashref of variable names (including sigils) to value references. there can be more than one lexical environment (each one maintained by a different plugin), so plugins that want to inspect the lexical environment should call"$self->publish('lexical_environment')"and then merge together all of the hashrefs that come back. πpackageβ plugins that want to modify the currently active package should do it by implementing this message, which should return the name of the current package. then, to access the currently active package, a plugin can call"($self->publish('package'))[-1]". π
and no, your plugins are not limited to these messages β you can use literally whatever messages you want to communicate. go off. π«Ά
π METHODS π
π publish ($name, @args)
publish a message to the other plugins that respond to it. every loaded plugin that implements a method named $name will have it called with @args as the parameters. returns a list of everything each plugin responded with. group chat, but for code. π£
π commands
returns the names of the "#" commands that this plugin implements. you can use this with "publish" β "$plugin->publish('commands')" will return a list of all the commands available in the current Reply session. so handy. so cute. π
π§ AUTHOR π§
Jesse Luehrs <doy@tozt.net> β the icon, the legend, the main character. π
πΈ COPYRIGHT AND LICENSE πΈ
this software is Copyright (c) 2016 by Jesse Luehrs.
this is free software, licensed under:
The MIT (X11) License
and that's the whole page bestie!! no cap, you now know Reply::Plugin better than most people who've been writing Perl for years. iykyk π
little sign-off from the very bottom of the original: this was documented forperl v5.34.0and the page is dated2022-06-17. thanks for reading, go write a plugin, mwah π«Άβ¨π
π¦ where this page comes from
- debian bookworm: libreply-perl 0.42-2 Β· MIT
- debian trixie: libreply-perl 0.42-2 Β· MIT
- ubuntu noble: libreply-perl 0.42-2 Β· MIT
- ubuntu resolute: libreply-perl 0.42-2 Β· MIT
- ubuntu stonking: libreply-perl 0.42-2 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms