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;
| [reply] [d/l] [select] |
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
| [reply] [d/l] |
|
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;
| [reply] [d/l] |
|
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
| [reply] |
|
|
Re: Extend a module
by Transient (Hermit) on Jul 06, 2009 at 17:32 UTC
|
| [reply] |
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
| [reply] [d/l] [select] |
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.
| [reply] [d/l] |
Re: Extend a module
by pemungkah (Priest) on Jul 08, 2009 at 04:12 UTC
|
There are two three main ways:
- 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.
- 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!"
- 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.
| [reply] |