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

Extend a module

by Anonymous Monk
on Jul 06, 2009 at 17:29 UTC ( [id://777607]=perlquestion: print w/replies, xml ) Need Help??

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

I don't know if these are the right words or terms to use to describe what I want to do. Say I load any module, and I want to add a method to it like if I load Net::FTP and I wanted to add a method, how would I do that?

Replies are listed 'Best First'.
Re: Extend a module
by moritz (Cardinal) on Jul 06, 2009 at 17:33 UTC
    You subclass it, and instead of useing the original Net::FTP, you load your child class instead.
    package Your::Net::FTP; use parent 'Net::FTP'; use strict; use warnings; sub your_new_method { ... } 1;
Re: Extend a module
by CountZero (Bishop) on Jul 06, 2009 at 18:22 UTC
    OR if you want to stay within the same namespace and not write a specific module for it:
    use Net::FTP; package Net::FTP; sub my_new_FTP_method { ... }; package main; # your script here $ftp = Net::FTP->new("some.host.name", Debug => 0) or die "Cannot connect to some.host.name: $@"; $ftp->my_new_FTP_method;

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      another way to do it is to just add the package name to the method declaration:
      use Net::FTP; sub Net::FTP::my_new_FTP_method { ... }; # your script here $ftp = Net::FTP->new("some.host.name", Debug => 0) or die "Cannot connect to some.host.name: $@"; $ftp->my_new_FTP_method;
        The only difference being that you must then add "Net::FTP::" to all your (non lexical) variables in the subroutine as well, otherwise they get compiled in the "main::" package and that can get rather confusing.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Extend a module
by Transient (Hermit) on Jul 06, 2009 at 17:32 UTC
Re: Extend a module
by jeanluca (Deacon) on Jul 06, 2009 at 20:37 UTC
    I just want to mention Class::Trait. It might be interesting
    Example: my executable:
    #! /usr/bin/perl use warnings ; use MyModel ; use newModel ; my $m = MyModel->new() ; Class::Trait->apply( $m, newModel ) ; # polymorphic stuff here :) $m->test() ; $m->newTest() ;
    and the the modules MyModule.pm
    package MyModel ; sub test { print "MyModel\n" ; } sub new { return bless {}, __PACKAGE__ ; } return 1 ;
    and newModel.pm:
    package newModel ; use Class::Trait 'base' ; sub test { print "add test\n" ; } sub newTest { print "add new test\n" ; } return 1 ;
    Maybe not a very good example, but in your case you can replace MyModule (I think) with Net::FTP, this way you should be able to add new or replace existing subs in Net::FTP

    Cheers
    LuCa
Re: Extend a module
by ruzam (Curate) on Jul 07, 2009 at 13:57 UTC
    package your::Net:FTP; use strict; use warnings; # make your::Net::FTP inherit all the methods of Net::FTP use base qw( Net:FTP ); # now you're free to redefine/override what ever you want # our new method replacement sub new { # call the original Net::FTP new method my $ftp_obj = shift->SUPER::new(@_) or return 0; # add our custom code $ftp_obj->{my_data} = 'test'; return $ftp_obj; } # and method all our own sub my_function { my $ftp_obj = shift; # do some stuff }

    When you 'use base' your custom module automatically 'inherits' all the methods of it's parent. You're free to replace any of them (or add new methods of your own). If you need to call methods of the parent package directly, then prefix the method name with 'SUPER::' and you'll get the original method.

Re: Extend a module
by pemungkah (Priest) on Jul 08, 2009 at 04:12 UTC
    There are two three main ways:
    1. Subclassing the module - this lets you add your own methods to the class, and replace or extend methods that are already there.

      Advantage: you write very little code, and your code stays disjoint from the already-existing code.

      Disadvantage: code that needs "your stuff" has to use your new subclass instead of the standard one; if you have code that already uses the old class a lot, you have to go through and change all of the class mentions from the old one to your new one.

    2. Patching the module. There are several ways to go about this (cpan:Sub::Exporter, cpan:Class::AutoPlug, but all of them boil down to manipulating the symbol table to add your new method to the desired namespace.

      Advantage: it looks like you're using bog-standard Module::X, but you get your extension.

      Disadvantage: less understandable to less-experienced programmers. "But magic_method isn't there when I do perldoc Module::X!"

    3. Extending the class by switching namespaces via package, creating the method or methods you want, and returning to your old package.

      Advantage: simpler than the other two. Disadvantage: the package switch needs to occur after the package has been used, but before the method is needed.

      Disadvantage: this adds a execution-order linkage between the module you're extending and the one you extend it in: the module has to be loaded, then your package statement and the sub definition have to be compiled, then after that the method's available. This might get complicated if you do a lot of patching.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://777607]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-20 01:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found