Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re-using/changing a class

by Anonymous Monk
on Feb 09, 2001 at 23:46 UTC ( #57457=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello people,

I am a fairly new Perl programmer, and have a quick question:

Let's say I have a simple script called Temp.pl. Temp.pl uses a class called Myclass.pm. During runtime, I change something in the Myclass.pm file. How can I re-'use' Myclass.pm? (Which would basically recompile it, with my changes added.)

I've tried embedding another 'use Myclass;' inside of my code, but apperantly it doesn't go get the source again. My goal is to have a dynamic program which uses several of my own classes. The classes' source can be changed, and then (hopefully) reimplemented back into my original program as a new object.

Thanks for your help,
Michael Whitaker

Comment on Re-using/changing a class
Re: Re-using/changing a class
by Trinary (Pilgrim) on Feb 09, 2001 at 23:56 UTC
    You have to take the module out of the %INC structure, then do another require Myclass import Myclass; For doing dynamic module loading, I'd avoid 'use', replace em with requre/import. use (I think) builds a list of modules at compile time, and dosen't allow for much dynamic voodoo to be pulled.

    Enjoy!

    Trinary

    Update:Should be more clear, you need to delete the key "Myclass" from %INC...if the actual Myclass has some ::s in it, they're converted to / s when it's put into %INC.

Re: Re-using/changing a class
by mr.nick (Chaplain) on Feb 10, 2001 at 00:36 UTC
Re: Re-using/changing a class
by Fastolfe (Vicar) on Feb 10, 2001 at 01:49 UTC
    If you want to re-define a subroutine in a module to suit your needs, consider either creating a descendant class or use eval to re-define the subroutine:
    package MyClass2; use MyClass; use Exporter; @ISA = ('MyClass'); @EXPORT = @MyClass2::EXPORT; sub overridden { print "This is *my* method, overriding MyClass::overridden!\n"; }
    Or:
    #!/usr/bin/perl use MyClass; sub MyClass::overridden { print "I need this to behave differently.\n"; }
    Or:
    #!/usr/bin/perl use MyClass; my $code = get_some_code_text; eval "sub MyClass::overridden { $code }";
    Using eval in this way lets you completely re-define your functions internally, even stuff in other modules, without needing to write your changes in a new file and then "re-use" (re-execute) that file to get your changes to take effect. Persistency might be a good reason to want to edit the source directly, though, so I understand that.
Re: Re-using/changing a class
by Mantic (Initiate) on Feb 10, 2001 at 02:29 UTC
    This is the original poster; got an account

    Thanks for all the help, it works great! But there is a little catch (as there is always a little catch): because I used the -w option, it gives me a redefinition warning for each method in that class. I deleted the old class from @INC, and re 'required' it again, as mentioned above, so wouldn't all of the old sub's in that class get deleted as well? (Hence, not stating a redefinition of its subs.)

    I could use the $^W = 0; trick inside of the class, but most of my program is made up of classes, and I don't want to disable warnings.

      You can also eliminate the warning by doing:

      undef \&flipBits if defined \&flipBits;

      You could either put this in the module (in which case you'd put it inside a BEGIN block before the subroutine(s) in question) or you could even loop over the symbol table of the module... If you import subroutines, I think you'll also get warnings for re-importing them.

      Note also that the module needs to be aware that it might be "reused" so that it initializes properly in that case. Many modules won't have a problem here, but some will.

              - tye (but my friends call me "Tye")
      Have a look at the the delete_package('Foo::Bar') function in the standard module Symbol. That way you can clear the module from memory before telling perl that it isn't loaded.
Re (tilly) 1: Re-using/changing a class
by tilly (Archbishop) on Feb 10, 2001 at 06:21 UTC
    Why are you changing the behaviour of the class?

    Depending on the problem, a pattern that may fit very well is to have a base class and several classes that inherit from it (each one being a "state") and then call bless to change your object from one class to another, to another and back to the first.

    If you want a particular method to be doing one of several fixed things, this is probably a much cleaner solution than what you are using right now.

Re: Re-using/changing a class
by Crulx (Monk) on Feb 10, 2001 at 16:42 UTC
    Ahh, wisdom you seek. And some wisdom different from what you see here I can provide. You have a class Myclass yes?
    use strict; package Myclass; sub foo { return 1; } 1;
    Seeing the folly of your ways, you come to realize that the code must be
    use strict; package Myclass; sub foo { return 42; } 1;
    Search this program below for the answer
    use strict; use Myclass; print "Foo is " . &Myclass::foo . "\n"; print "Modify the file and hit enter\n"; <STDIN>; do 'Myclass.pm'; print "Foo is " . &Myclass::foo . "\n";
    And thus does "do". But note, that if we delete foo, the function remains in the symbol table, and thus stays. A more through approach would clobber the table elements from the package. Class variables are vulnerable as well. And use warnings will warn.

    In your service,
    ---
    crulx
    crulx@iaxs.net

Re: Re-using/changing a class
by Mantic (Initiate) on Feb 13, 2001 at 04:32 UTC
    Hey, thanks a lot for the help!

    As things have worked out, this is what I've done:
    sub reloadClass { delete_package("Myclass"); do 'Myclass.pl'; }

    With this setup, I can change the code of Myclass during runtime without any errors or warnings. I could replace "do 'Myclass.pl'" with the "delete...; require..." type coding.

    For those who are curious: for me to get interested in learning a language I need to have a drive or ambition. This usually comes in the form of a personal project and the like. As a 'less then 1 month' perl monkino, I'm aiming in creating a perl MUD server which can be programmed through a client in the server itself. They would be programming the "Myclass.pl" equivalent and restarting it. The equivalent would be, for example, the skill database and interpreter.

    But anyway, thank you all for the help!
    ~MichaelD

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://57457]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (19)
As of 2014-09-16 17:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (40 votes), past polls