How to make the "final" method in Perl?

I was wondering if it is possible to make sure that the method in the class that I am doing will NOT be patched by a monkey ( Monkey Patch ). Can Lose achieve this?

Consider the following:

{
  package Foo;
  sub hello{print "HI"}
1;
}

package main;
sub Foo::hello {print "bye"}

Foo::hello()#bye
+5
source share
4 answers

After a quick web research, I found this thread on Perlmonks, which reads:

Regarding the declaration of final methods, I'm not sure how you will do this without doing something really interesting to intercept all the additions to the symbol table. (Can this be done?).

I would also suggest that this is impossible.

Moose, , , . , , ,

before "hello" => sub{ # check if hello has been tampered with
                   }

, , , , !

, , perl , , , , .

+4

Perl final, . :

BEGIN {
    package final;
    $INC{'final.pm'}++;
    use Variable::Magic qw(wizard cast);
    sub import {
        my (undef, $symbol) = @_;
        my ($stash, $name)  = $symbol =~ /(.+::)(.+)/;
        unless ($stash) {
            $stash  = caller().'::';
            $name   = $symbol;
            $symbol = $stash.$name;
        }
        no strict 'refs';
        my $glob = \*$symbol;
        my $code = \&$glob;
        my ($seen, @last);

        cast %$stash, wizard store => sub {
            if ($_[2] eq $name and $code != \&$glob) {
                print "final subroutine $symbol was redefined ".
                      "at $last[1] line $last[2].\n" unless $seen++
            }
            @last = caller
        }
    }
}

:

use warnings;
use strict;
{
    package Foo;
    sub hello {print "HI"}
    use final 'hello';
}

package main;
no warnings;
sub Foo::hello {print "bye"}

Foo::hello();

- :

final subroutine Foo::hello was redefined at filename.pl line 9.
bye

, , (- perl Variable::Magic). , .

no warnings; , perl . , , use warnings . :

Perl . , , , .

+3

Monkey, .

#./FooFinal.pm
package FooFinal;
use strict;
use warnings;
sub import { warnings->import(FATAL => qw(redefine)); }
sub hello { print "HI" }
1;

#./final_test.pl
#!/usr/bin/env perl
use strict;
use warnings;
use FooFinal;
sub FooFinal::hello {print "bye".$/}

FooFinal->hello();#bye

print 'still living!!!'

, . /final _test.pl " !!!". , "un-patchable", /. , " ":) : " !"

, " Monkey Patching Perl?"... , perlexwarn ...

+1

All Articles