Re: OO perl query
by friedo (Prior) on Nov 03, 2005 at 14:10 UTC
|
When you're writing object-oriented classes, the easiest thing to do is make everything a method, whether it strictly needs to be or not. Then you always have a $self, and you can always use it to call other methods. | [reply] |
|
|
friedo,
I agree when we are talking about calling methods within methods internal to a class. It is not too uncommon though to want to provide non-OO functionality to modules (see CGI for instance). Perl doesn't natively support multi-method dispatch so we have to devise our own solution* in these cases. One way is to examine the parameters yourself and behave accordingly.
* There are of course modules that can make this easier but they are still not core functionality. Perl6 will correct this deficiency.
| [reply] |
Re: OO perl query
by Limbic~Region (Chancellor) on Nov 03, 2005 at 14:16 UTC
|
rsennat,
I have a doubt in OO Perl usage. ... Thanks and hope the question is clear.
I believe it is generally more popular to use "question" where you used "doubt". That was easy to figure out. The second part of the question is a bit more confusing, but it sounds like you want to know how a method can be treated as a method or a regular subroutine.
If that is the case, parameter checking can help:
sub generate_hash {
my $self;
if ( ref $_[0] && @_ == 4 ) {
# We were called as a method
$self = shift;
}
my ($i, $j, $k) = @_;
}
Now this is still not perfect but you know better than I what error conditions you need to handle. I also do want to mention that there should be no need for this. You can call one method inside another method without needing to treat it as a regular subroutine:
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->_initialize(@_);
return $self;
}
sub _initialize {
my $self = shift;
# Do stuff with @_
}
As you can see, the method call works inside the method just fine. Typically the only reason you would want to change behavior based off parameters is if you wanted to provide modules with the option of non-OO functionality.
| [reply] [d/l] [select] |
Re: OO perl query
by davidrw (Prior) on Nov 03, 2005 at 14:14 UTC
|
You can invoke it like Foo::Bar->generate_hash($i, $j, $k) instead of $obj->generate_hash($i, $j, $k) so that 'Foo::Bar' gets shift'd off, BUT only if the generate_hash() method doesn't invoke any methods on $self that require an actual object instead of just the class name ... (whether this is actually good OO practice or not, i'll leave that for others to comment on)
| [reply] [d/l] [select] |
Re: OO perl query
by japhy (Canon) on Nov 03, 2005 at 14:31 UTC
|
If you want to know how to create a class-method or object-method that can also work as an independent function, there are two ways I would feel comfortable doing it:
- If the function take a constant number of arguments, use that to determine how it was called:
# $obj->fooify(1,2,3) or fooify(10,20,30)
# always expects 3 "real" args
sub fooify {
my $self;
$self = shift if @_ == 4; # if 4 args, the first is the object/clas
+s
my ($x, $y, $z) = @_;
# ...
}
- If you can be quite sure the arguments will never be the name of a subclass or an object in a subclass of the class you're in, you can do:
sub fooify {
my $self;
$self = shift if UNIVERSAL::isa($_[0], __PACKAGE__);
my ($x, $y, $z) = @_;
# ...
}
| [reply] [d/l] [select] |
Re: OO perl query
by kirbyk (Friar) on Nov 03, 2005 at 22:40 UTC
|
While I share some skepticism about whether you're doing things the Right Way that others have brought up, sometimes life doesn't work out that way, and you may have some need to work with legacy code. Don't _try_ to mix and match OO and functional, but if you have to be there....
One approach that works pretty well is to have a wrapper function, that can call the functional code. Like:
sub oo_generate {
my $self = shift;
return func_generate(@_);
}
sub func_generate {
my ($i, $j, $and_other_bad_variable_names) = @_;
...
}
This doesn't work as well if you want to do stuff with the object variables, more than pass them into functions, but it's a reasonable way to abstract something in transition. Later, if you manage to deprecate the functional subroutine, you can put all the code back into the object method without having to change the interface.
| [reply] [d/l] |
Re: OO perl query
by rsennat (Beadle) on Nov 03, 2005 at 14:24 UTC
|
Oops. It is a question and not a doubt.
Anyway, so using $self we can refer to the method as subroutine.
Fine and thanks all for the immd. support.
| [reply] |