in reply to Re^2: How to redefine a modules private function?
in thread How to redefine a modules private function?

You can avoid hitting the disk (even though that's great for debugging) by using an in-memory file in your @INC hook:

open my $out, \my $buffer or die "Couldn't patch AnyEvent::DNS; your Perl do +es not support in-memory filehandles"; while (<$in>) { s/sub\s+DOMAIN_PORT\b/sub DOMAIN_PORT () { 1053 } +sub FORMER_DOMAIN_PORT/; $buffer .= $_; } return $out;

Replies are listed 'Best First'.
Re^4: How to redefine a modules private function?
by salva (Canon) on Mar 09, 2022 at 11:24 UTC
    Ok, here it is the full solution using an in-memory file:
    use strict; use warnings; use Path::Tiny; sub hotpatch { my ($self, $module) = @_; if ($module eq 'AnyEvent/DNS.pm') { for my $inc (@INC) { next if ref $inc; if (open my $in, '<', path($inc)->child($module)) { my $buffer = do { undef $/; <$in> }; $buffer =~ s/\bsub\s+DOMAIN_PORT\b/sub DOMAIN_PORT () +{ 1053 } sub FORMER_DOMAIN_PORT/; open my $out, '<', \$buffer or die "Couldn't patch AnyEvent::DNS; your Perl do +es not support in-memory filehandles"; return $out; } } warn "couldn't patch AnyEvent::DNS"; } return undef; } BEGIN { unshift @INC, \&hotpatch } use AnyEvent::DNS; BEGIN { @INC = grep not(ref and $_ eq \&hotpatch), @INC } say AnyEvent::DNS::DOMAIN_PORT(); say AnyEvent::DNS::FORMER_DOMAIN_PORT();

      Nice! That's like a more concise version of what I posted here.

      Nice.

      But when used in production, I'd suggest to check if the regex was successful and raise an error otherwise.

      This is practically a source filter, and the patched source could change between versions. (like implementing a variable port)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery