Perl monkeypatch/extension



  • Disclaimer: Essentially I've inherited a small perl project because our hardware provider doesn't have availability to perform the task we need in a timely manner. I have no previous experience programming in perl and I don't really have time to learn the ins and outs of the language at the moment. The sequence of things we need to have the code do are not the issue, what we need is to be able to inject the new functionality into the existing code without modifying any code maintained by the hardware provider. The package looks like:

    package pkg::name::foo::bar;
    use strict;
    use warnings 'all';
    my $arr = {
         'action/a'=>sub { ... },
         'action/b'=>sub { ... },
         'action/c'=>sub { ... },
    }
    sub fizz { #uses $arr }
    

    At the moment I'm pretty unsure on all of the steps I need to do in order to integrate our new "action" into the list, including:

    1. the best method to add the new action (e.g. monkey patching or extending the package),
    2. how to overcome the my modifier of $arr, and
    3. how the changes would be added to the scope, preferably automagically, so we don't need to modify the existing executing code.

    Any resources that you all could point me to relating to these topics would be helpful.





  • @holli said:

    http://www.perlmonks.org/

    I was hoping for something slightly more specific. I found that site and others days ago. I'm having trouble figuring out what parts of it and other perl sites are useful for my problem without learning everything about perl, and I was hoping for a pointer towards some generic tutorial that might help with any of my 3 problems. I'm not trying to learn perl; I'm trying to solve a very specific problem. Sorry if I was not clear about this before.



  • I'll start out by saying that I have no idea whether monkeypatching this is possible, nor, if possible, how to do it, so my comments are entirely related to extending it.

    I think the my pretty much eliminates any chance of extending this without modifying the existing code. If you can modify it to the extent of s/my/our/, then I think extending it is straightforward.



  • @HardwareGeek said:

    I'll start out by saying that I have no idea whether monkeypatching this is possible, nor, if possible, how to do it, so my comments are entirely related to extending it.

    I think the my pretty much eliminates any chance of extending this without modifying the existing code. If you can modify it to the extent of s/my/our/, then I think extending it is straightforward.

    Looks like you're right on the my part of things; some more SO reading since I wrote the OP seems to indicate that it's impossible to patch without using something like PadWalker.



  • @rad131304 said:

    Looks like you're right on the my part of things; some more SO reading since I wrote the OP seems to indicate that it's impossible to patch without using something like PadWalker.
    Interesting. I had never heard of PadWalker (although apparently I've used it many times, since it is used internally by the perl debugger). If I read the docs right, even PadWalker will only let you patch the code if you can somehow get it to call your code from somewhere that $arr is in scope, and getting it call your code is the whole point of patching it. Seems like a Catch-22.



  • @rad131304 said:

    package pkg::name::foo::bar;
    use strict;
    use warnings 'all';
    my $arr = {
         'action/a'=>sub { ... },
         'action/b'=>sub { ... },
         'action/c'=>sub { ... },
    }
    sub fizz { #uses $arr }

    "My"-variables are lexical and thus can't be accessed outside the scope, but subs are not:

    use PadWalker qw(peek_sub);
    ${peek_sub(\&pkg::name::foo::bar::fizz)->{'$arr'}}->{'action/d'} = sub { ... };


  • @Faxmachinen said:

    @rad131304 said:

    package pkg::name::foo::bar;
    use strict;
    use warnings 'all';
    my $arr = {
    'action/a'=>sub { ... },
    'action/b'=>sub { ... },
    'action/c'=>sub { ... },
    }
    sub fizz { #uses $arr }

    "My"-variables are lexical and thus can't be accessed outside the scope, but subs are not:

    use PadWalker qw(peek_sub);
    ${peek_sub(\&pkg::name::foo::bar::fizz)->{'$arr'}}->{'action/d'} = sub { ... };

    That looks quite promising. Do you know, offhand, if the actual code behind peek_sub simple enough to possibly be directly implemented instead of using PadWalker? There's limited memory, storage, and CPU cycles on the hardware and I don't want to have to load a large library that could interfere with the device's primary function. Admittedly, I don't know how package scope relates to memory footprint in perl, but I have heard that perl is not known for it's memory efficiency, so if I don't need to be worried about it then please let me know.


Log in to reply