Perl OO - combined static & instance method.

R

RedGrittyBrick

An instance method in traditional Perl OO might be like this.

Package Foo;
...
sub bar {
my $self = shift;
my ($x, $y, $z) = @_;
...
}

I'd like to be able to invoke this either as a (static) class method
$result = Foo::bar(1,2,3);

or as an instance method
my $foo = Foo->new(Foo::INVERTED);
$result = $foo->bar(1,2,3);

What is the usual idiom for checking for the presence of the class ref?.
 
U

Uri Guttman

R> An instance method in traditional Perl OO might be like this.
R> Package Foo;
R> ...
R> sub bar {
R> my $self = shift;
R> my ($x, $y, $z) = @_;
R> ...
R> }

R> I'd like to be able to invoke this either as a (static) class method
R> $result = Foo::bar(1,2,3);

that is not a method at all. that is a plain sub call. the only way to
tell if it isn't a method is to check the first arg and see if it is a
blessed object of that class.

R> or as an instance method
R> my $foo = Foo->new(Foo::INVERTED);

that is a class method call

R> $result = $foo->bar(1,2,3);

that is an instance or object method call. those you can differentiate
by looking at the first arg. but it is a BAD idea for one method to
support both styles. there are idioms for allowing the new() (or other)
methods work both ways but it is better to have different methods for
each api style

R> What is the usual idiom for checking for the presence of the class ref?.

there is no standard way to tell a method call from a plain sub call as
you never want to use the same sub both ways. if you could call a method
without its object, what is the point of making it a method to begin
with?

uri
 
W

Willem

RedGrittyBrick wrote:
) An instance method in traditional Perl OO might be like this.
)
) Package Foo;
) ...
) sub bar {
) my $self = shift;
) my ($x, $y, $z) = @_;
) ...
) }
)
) I'd like to be able to invoke this either as a (static) class method
) $result = Foo::bar(1,2,3);
)
) or as an instance method
) my $foo = Foo->new(Foo::INVERTED);
) $result = $foo->bar(1,2,3);
)
) What is the usual idiom for checking for the presence of the class ref?.

That there above is not a static class method call. This is:

$result = Foo->bar(1,2,3);


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
R

RedGrittyBrick

R> An instance method in traditional Perl OO might be like this.
R> Package Foo;
R> ...
R> sub bar {
R> my $self = shift;
R> my ($x, $y, $z) = @_;
R> ...
R> }

R> I'd like to be able to invoke this either as a (static) class method
R> $result = Foo::bar(1,2,3);

that is not a method at all. that is a plain sub call. the only way to
tell if it isn't a method is to check the first arg and see if it is a
blessed object of that class.

R> or as an instance method
R> my $foo = Foo->new(Foo::INVERTED);

that is a class method call

R> $result = $foo->bar(1,2,3);

that is an instance or object method call. those you can differentiate
by looking at the first arg. but it is a BAD idea for one method to
support both styles. there are idioms for allowing the new() (or other)
methods work both ways but it is better to have different methods for
each api style

R> What is the usual idiom for checking for the presence of the class ref?.

there is no standard way to tell a method call from a plain sub call as
you never want to use the same sub both ways. if you could call a method
without its object, what is the point of making it a method to begin
with?

Thanks for clearing up my misunderstanding.

The background is that I have a handful of programs, the earlier ones
have some subroutines in common so these were moved into a common
procedural module. A set of programs written later use an OO version of
the module. I wanted to merge the OO and procedural modules whilst
delaying the refactoring of the earlier programs.
 
R

Randal L. Schwartz

RedGrittyBrick> The background is that I have a handful of programs, the
RedGrittyBrick> earlier ones have some subroutines in common so these
RedGrittyBrick> were moved into a common procedural module. A set of
RedGrittyBrick> programs written later use an OO version of the
RedGrittyBrick> module. I wanted to merge the OO and procedural modules
RedGrittyBrick> whilst delaying the refactoring of the earlier programs.

You should have said this first. The solution is simple:

Use a global substitution on the older programs to replace
"Your::Module" with "Your::Module::Legacy". Then create a subroutine in
that package that invokes the correct method in "Your::Module".

Simple.

Most people work too hard. :)

print "Just another Perl hacker,"; # the original
 
R

RedGrittyBrick

RedGrittyBrick> The background is that I have a handful of programs, the
RedGrittyBrick> earlier ones have some subroutines in common so these
RedGrittyBrick> were moved into a common procedural module. A set of
RedGrittyBrick> programs written later use an OO version of the
RedGrittyBrick> module. I wanted to merge the OO and procedural modules
RedGrittyBrick> whilst delaying the refactoring of the earlier programs.

You should have said this first.

I should. The trouble was I half remembered something of the sort that
Sherm helpfully pointed out. Plus I hadn't thought through the implications.

The solution is simple:

Use a global substitution on the older programs to replace
"Your::Module" with "Your::Module::Legacy". Then create a subroutine in
that package that invokes the correct method in "Your::Module".

Simple.

My thoughts had turned to writing wrappers, thanks for the additional
organisational hints.

Most people work too hard. :)

I obviously still have to work on increasing my laziness, impatience and
hubris†.
 
W

Willem

Randal L. Schwartz wrote:
)
)RedGrittyBrick> The background is that I have a handful of programs, the
)RedGrittyBrick> earlier ones have some subroutines in common so these
)RedGrittyBrick> were moved into a common procedural module. A set of
)RedGrittyBrick> programs written later use an OO version of the
)RedGrittyBrick> module. I wanted to merge the OO and procedural modules
)RedGrittyBrick> whilst delaying the refactoring of the earlier programs.
)
) You should have said this first. The solution is simple:
)
) Use a global substitution on the older programs to replace
) "Your::Module" with "Your::Module::Legacy". Then create a subroutine in
) that package that invokes the correct method in "Your::Module".

Why not use a global substitution to replace
"Your::Module::(\w+)" with "Your::Module->$1" ?

This should work as long as there are no module variables in use, no ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
R

Randal L. Schwartz

Willem> Why not use a global substitution to replace
Willem> "Your::Module::(\w+)" with "Your::Module->$1" ?

Might miss imports. Mine'll work either way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top