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

Okay, I am done with the code I would like my new submodule to MP3::Napster contain. I have added several methods and a bunch of variables. I'm going to paraphrase the module below and then ask my questions so theyre in a relevant context.
# MP3::Napster, by Lincoln Stein package MP3::Napster; use MP3::Napster::MessageCodes; sub new { my $class = shift; # create and store the server object if (my $servobj = MP3::Napster::Server->new($server,$self,$metaserve +r)) { $self->server($servobj); } else { $self->disconnect; return; } $self->install_default_callbacks; $self; }
MP3::Napster::MessageCodes.pm looks like this:
package MP3::Napster::MessageCodes; require Exporter; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); @ISA = qw(Exporter MP3::Napster::Base); @EXPORT = qw(JOIN_ACK MOTD TIMEOUT TRANSFER ABORTED); 1;
What I would like to do is create a new module, MP3::Napster::OpennapMessageCodes.pm and another new module, MP3::Napster::Opennap. I have created a new 20-25 methods to add to the MP3::Napster.pm module, but they should be contained in another module. I have also created a new hash with message codes as they appear in the opennap source. How do I make these two modules part of the parent module without the parent module specifying them? In other words, how can I distribute a module that will make available methods to an object created from its parent module without the parent module having to be modified?

My second question is can I create a new MessageCodes module that will contain values in @EXPORT that are also in the "stock" MessageCodes module? Im pretty sure I can since theyre in a hash.

Thanks again, everyone. I think I will be writing a small module-howto when I get this whole thing done. By the way, I have Damian Conway's book. However, I am kind of at a loss on where and how to start with this. His book takes things from the perspective of creating a module, and thats not strictly what I am doing here.

dep.

--
i am not cool enough to have a signature.

Replies are listed 'Best First'.
Re: How do I create a submodule transparent to its parent without modifying the parent?
by eg (Friar) on Jan 28, 2001 at 23:31 UTC

    I find what you're doing a little confusing. If you want to add methods to MP3::Napster, you can certainly do that by having a second module that also defines things in the MP3::Napster namespace. For example, if your module is in ~/lib/MyNapster.pm,

    package MP3::Napster; # *not* "package MyNapster;" sub blah1 { ... sub blah2 { ... sub blah3 { ... 1;

    and then in your code you would have to use both modules to make your methods available.

    #!/usr/bin/perl -w use strict; use MP3::Napster; use MyNapster; my $nap = MP3::Napster->new(); $nap->blah1(); ...

    But that seems, well, odd. Certainly not in the spirit of the object oriented philosphy of encapsulation. Why not just subclass MP3::Napster? (In spite of what you say, depricated, I do think that you're creating a module -- a module that inherits and relies heavily on another, but that's exactly what oop is supposed to do.) Again, if your module is at ~/lib/MyNapster.pm,

    package MyNapster; @MyNapster::ISA = qw / MP3::Napster /; sub blah1 { ... sub blah2 { ... sub blah3 { ... 1;

    and then, essentially use MyNapster as you would MP3::Napster, but with your enhancements.

    #!/usr/bin/perl -w use strict; use MyNapster; $nap = MyNapster->new(); $nap->blah1(); ...

    There are a couple perl oop/module tutorials out there including perlmod, perlmodlib, perltoot, perlobj and perlbot. You ought to consult them before writing your howto to avoid doing redundant work. But fresh, new documentation is always appreciated!

    HTH, Eric

(tye)Re: How do I create a submodule transparent to its parent without modifying the parent?
by tye (Sage) on Jan 29, 2001 at 07:26 UTC
    package MP3::Napster::OpennapMessageCodes; require MP3::Napster; push @MP3::Napster::ISA, "MP3::Napster::OpennapMessageCodes";

    Simple enough for you? I'm not sure I would highly recommend it, though. (:

            - tye (but my friends call me "Tye")
      Tye (can I call you "Tye"?), I'm not sure sure I understand what youre doing there, but it seems like a rather rude (from a code-ethics standpoint, not your suggestion) way to do things. Correct me if im wrong:
      • There's an @ISA in MP3::Napster.
      • It says it "is a" @ISA = qw(Exporter MP3::Napster::Base).
      • You're (! highly) recommending that I forcibly convince MP3::Napster that it is actually a module of type MP3::Napster::OpennapMessageCodes ?

      Let me know if I've got this right. I will be posting my solution probably tomorrow. Chromatic didnt do us all the favor of posting publically, but gave me an excellent suggestion in /msg. (speak up, chromatic! heh!)

      dep.

      --
      i am not cool enough to have a signature.

        I never said I recommend it, just that I don't highly recommend it. Yes, it is a rude thing to do. But the request was "I have created a new 20-25 methods to add to the MP3::Napster.pm module", "wihout modifying the parent". Seems like a pretty rude thing to want to do.

        If one is going to be rude, one might as well be rude in a very simple way than in a complex way.

        Note that it is "unrude" in that

        • If you don't require the new module(s), then MP3::Napster is completely unaffected.
        • Anything that MP3::Napster already inherits from takes precedence over these new module(s) because I used push and not unshift (and because I force MP3::Napster to be initialized before I do the push).
        So I'm on the fence as to whether one should ever do what I wrote or what was originally asked for, but I don't understand why you would need to do that. I'd probably create a separate class that inherits from both MP3::Napster and these new modules.

                - tye (but my friends call me "Tye")
Re (tilly) 1: How do I create a submodule transparent to its parent without modifying the parent?
by tilly (Archbishop) on Jan 29, 2001 at 02:53 UTC
    You are doing the opposite of inheritance. :-)

    Normally you would write the subclass and use the subclass. The subclass gets methods from both the parent and itself, without needing to include the parent in itself. Going the other way would be seriously problematic. Somewhere you need to load the module that implements the subclass, and somewhere you need to place its functionality where needed.

    As for your import question, you will need to do some work. Off of the top of my head I might suggest just initializing your @EXPORT and @EXPORT_OK to be your parents, and then either import all of the method into your space, or else have an AUTOLOAD that will import and rethrow at run-time. (So it is slow the first time and faster afterwards.)

    I also suspect that when you are done this example you will find that if you go back and do it again you will see ways to improve and will learn a lot more. This usually is the case when learning something new, it is only with some experience that you get the insight you need to see how to use the ideas you learned in concrete problems.