Class::Refresh(3pm)

πŸ“¦
version 0.07 Β· 4 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble

πŸ’– Class::Refresh πŸ’–

okay bestie, welcome to Class::Refresh β€” she's a Perl module, she lives in the User Contributed Perl Documentation corner of your perldoc, and she does exactly one thing: she lets you refresh your classes during runtime. no restarting, no tears. 🫢


✨ VERSION ✨

version 0.07 β€” periodt.


🌸 SYNOPSIS 🌸

use Class::Refresh;
use Foo;

Class::Refresh->refresh;

# edit Foo.pm

Class::Refresh->refresh; # changes in Foo.pm are applied

like... that's it. that's the whole vibe. you change the file, you call refresh, the changes are applied. iconic behavior honestly. πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

so during development, it's super common to just cycle back and forth between writing code and testing that code. normally the testing happens inside your test suite, but ngl, sometimes it's way more convenient to just poke at things by hand while you're hunting down a bug, or while you're doing some exploratory coding. and in a lot of situations that gets inconvenient β€” like in a REPL, or in a stateful web application, restarting from the very beginning after every single code change is lowkey tedious. this module lets you reload your application classes on the fly, so the whole code/test cycle gets a lot easier. 🌈

this module takes a hash of import arguments, which can include:

  • track_require β€” if you set it, like:
use Class::Refresh track_require => 1;

then a require() hook gets installed to track modules which are loaded. this makes the list of modules to reload when refresh is called more accurate, but it may cause issues with other modules which hook into require β€” because the hook is global, bestie. global. 😭

now, the tea: this module has several limitations, because reloading modules this way is an inherently fragile operation. therefore, this module is recommended for use only in development environments β€” it should not be used for reloading things in production. don't do it. i'm serious. πŸ™ˆ

it also makes several assumptions about how code is structured that simplify the logic involved quite a bit, and make it more reliable when those assumptions hold, but do make it inappropriate for use in certain cases. for instance, this module is named Class::Refresh for a reason: it is only intended for refreshing classes, where each file contains a single namespace, and each namespace corresponds to a single file, and all function calls happen through method dispatch. unlike Module::Refresh, which makes an effort to track the files where subs were defined, this module assumes that refreshing a class means wiping out everything in the class's namespace, and reloading the file corresponding to that class. if your code includes multiple files that all load things into a common namespace, or defines multiple classes in a single file, this will likely not work. rip.


πŸ‘‘ METHODS πŸ‘‘

πŸŽ€ refresh

the main entry point to the module, the girlboss of the whole operation. the first call to refresh populates a cache of modification times for currently loaded modules, and subsequent calls will refresh any classes which have changed since the previous call. slay. ✨

πŸŽ€ modified_modules

returns a list of modules which have changed since the last call to refresh. it's giving receipts. 🧾

πŸŽ€ refresh_module $mod

this method calls unload_module and load_module on $mod, as well as on any classes that depend on $mod β€” for instance, subclasses if $mod is a class, or classes that consume $mod if $mod is a role. this ensures that all of your classes are consistent, even when dealing with things like immutable Moose classes. she's thorough, okay?? πŸ’…

πŸŽ€ unload_module $mod

unloads $mod, using Class::Unload. bye bestie πŸ‘‹

πŸŽ€ load_module $mod

loads $mod, using Class::Load. welcome back bestie 🫢


πŸ’€ CAVEATS πŸ’€

  • refreshing modules may miss modules which have been externally loaded since the last call to refresh

this is because it's not easily possible to tell if a module has been modified since it was loaded, if we haven't seen it so far. a workaround for this may be to set the track_require option in the import arguments (see above), although this comes with its own set of caveats β€” since it is global behavior. 😬

  • global variable accesses and function calls may not work as expected

Perl resolves accesses to global variables and functions in other packages at compile time, so if the package is later reloaded, changes to those will not be noticed. as mentioned above, this module is intended for refreshing classes. periodt.

  • file modification times have a granularity of one second

if you modify a file and then immediately call refresh and then immediately modify it again, the modification may not be seen on the next call to refresh. note however that file size and inode number are also compared, so it still may be seen, depending on if either of those two things changed. so like... maybe. πŸ™ƒ

  • tracking modules which use a given module isn't possible

for instance, modifying a Moose::Exporter module which is used in a class won't cause the class to be refreshed, even if the change to the exporter would cause a change in the class's metaclass. it's giving invisible. πŸ’€

  • classes which aren't completely defined in a single file and files which define multiple classes cause problems

if a class is defined across multiple files, there's no easy guaranteed way to restore the entire state of the class, since there may be load order issues. this includes Moose classes which have make_immutable called on them from outside of the class file itself.

also, files which define multiple classes cause problems since we can't always determine which classes are defined in the file, and so reloading the file may cause class definitions to be run more than once. not cute.

  • classes which build themselves differently based on the state of other classes may not work properly

this module attempts to handle several cases of this sort for Moose classes (modifying a class will refresh all of its subclasses, modifying a role will refresh all classes and roles which consume that role, modifying a metaclass will refresh all classes whose metaclass is an instance of that metaclass), but it's not a problem that's solvable in the general case. it's giving unsolvable, bestie.


πŸ› BUGS πŸ›

  • reloading classes when their metaclass is modified doesn't quite work yet

this will require modifications to Moose to support properly. so like... not our fault?? πŸ™ˆ

  • tracking changes to metaclasses other than the class metaclass isn't implemented yet
  • metacircularity probably has issues

refreshing a class which is its own metaclass will likely break. πŸ’€

please report any bugs to GitHub Issues at <https://github.com/doy/class-refresh/issues>.


🌈 SEE ALSO 🌈

Module::Refresh


🫢 SUPPORT 🫢

you can find this documentation for this module with the perldoc command.

perldoc Class::Refresh

you can also look for information at:

  • MetaCPAN

<https://metacpan.org/release/Class-Refresh>

  • Github

<https://github.com/doy/class-refresh>

  • RT: CPAN's request tracker

<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-Refresh>

  • CPAN Ratings

<http://cpanratings.perl.org/d/Class-Refresh>


⭐ CREDITS ⭐

this module was based in large part on Module::Refresh by Jesse Vincent. giving credit where credit is due, as always. πŸŽ€


πŸ’œ AUTHOR πŸ’œ

Jesse Luehrs <doy@tozt.net>


this software is copyright (c) 2014 by Jesse Luehrs.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole page bestie!! this one's from the Perl v5.26.1 era, dated 2018-03-31, and it lives under User Contributed Perl Documentation as Class::Refresh(3pm). go refresh something (in development only, i beg of you). πŸ’–βœ¨

πŸ“¦ where this page comes from