http://qs321.pair.com?node_id=682590

citromatik has asked for the wisdom of the Perl Monks concerning the following question:

Hi all

Recently, someone asked how to turn code back into source. The possibility of doing this, combined with the possibility of evaluate source into code during execution time permits editing code in situ, like in this dummy example:

use strict; use warnings; use B::Deparse; my $subref = sub {print "Hello\n"}; $subref->(); my $code = B::Deparse->new->coderef2text($subref); $code =~ s/print\s\S+/die "Bye";/; $subref = eval "sub $code"; $subref->();

Outputs:

Hello Bye at (eval 6) line 4.

I find this possibility amazing, and potentially useful, but apart from the module Sub::Compose (where this technique is used to combine several subroutines into one), I didn't find any other code that uses it. Have you ever seen this technique used in real code (apart from the commented example)? Is there any case where you can anticipate that this technique could be specially useful?

citromatik

Replies are listed 'Best First'.
Re: Is it useful to edit code at execution time?
by dragonchild (Archbishop) on Apr 24, 2008 at 14:54 UTC
    Yes, this is a very useful and cool thing to do. Other languages provide a more stable facility for this, such as Javascript, Lisp, and other functional langauges. (Yes, Javascript is more of a functional language than anything else.)

    That said, the facilities for this sort of thing aren't very good in Perl. The first problem is that there isn't a stable Perl parser, other than perl. PPI does as best you can and the author will freely admit there are simple snippets that it will simply fail on. Perl 6 will do this a lot better and, I suspect, you will see a lot more of this sort of thing when Perl 6 comes out, particularly with macros.

    For the record, I wrote Sub::Compose as an experiment for the pre-alpha version of Moose. When stvn and I were doing the initial spike that eventually became the pre- and post- processors for methods in Class::MOP, we were playing with restrictions on accessors. The idea was to have a bunch of simple-minded restrictions (cannot be undef, must have a certain length, must be greater than X, must be less than Y, etc). Then, you could chain those restrictions together in neat ways. Except, like everything in Perl that depends on a large number of tiny subroutines, performance was abysmal; the sub-calling overhead was just too high. So, I played around with making them all one subroutine and released that. You'll notice it's been a 0.01 for over 2 years. I honestly don't think anyone's ever used it. I've never received any email about it.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Is it useful to edit code at execution time?
by dvryaboy (Sexton) on Apr 24, 2008 at 15:22 UTC

    I can see using this when dealing with code that isn't mine. Sometimes you get a really useful library that now and then does something really boneheaded, like die() when it should really be warning, or explicitly committing a transaction to the database when you might still want to be able to roll back. For stuff like that, this technique could be really useful.

    However, for cases where I own all the pieces of the code.. why not just make the variable bits variables?