Re^4: Is it ok to mix functional and oo programming in one package?
by chromatic (Archbishop) on Oct 18, 2007 at 20:21 UTC
|
When it works, it is. The problem is that it doesn't always work. new Foo has two barewords, and whenever the Perl parser encounters barewords, it has to guess at what they are. Sometimes it has hints at what those barewords are (if it's encountered declarations of filehandles or subroutines) and it can guess correctly. Sometimes it doesn't have hints, because Perl embraces late binding.
Sometimes it has hints which contradict late binding altogether. There's where you run into problems, because you have to know exactly which hints matter and when the parser knows about them to diagnose and correct the problem.
Alternately, you could use a syntax which isn't ambiguous to the parser and has the benefit of clarifying what exactly happens (new not being a keyword in Perl as it is in some other languages with OO systems).
| [reply] [d/l] [select] |
|
| [reply] |
Re^4: Is it ok to mix functional and oo programming in one package?
by Joost (Canon) on Oct 18, 2007 at 20:35 UTC
|
To expand a bit on what chromatic said:
The key words in "method invocation using the METHOD CLASS_OR_INSTANCE LIST form is exactly equivalent to CLASS_OR_INSTANCE->METHOD (LIST) form." are "method invocation".
In other words, if new Foo is resolved by the perl parser as a method call it is exactly equivalent. The problem is that it isn't always. For instance, this works:
#!/usr/bin/perl
use warnings;
use strict;
my $a = new Foo;
$a->hello;
package Foo;
sub new {
return bless {},shift;
}
sub hello {
print "hello";
}
output:
hello
While this doesn't:
#!/usr/bin/perl
use warnings;
use strict;
sub new {
print "haha";
return;
}
my $a = new Foo;
$a->hello;
package Foo;
sub new {
return bless {},shift;
}
sub hello {
print "hello";
}
output:
Bareword "Foo" not allowed while "strict subs" in use at test.pl line
+10.
Execution of test.pl aborted due to compilation errors.
| [reply] [d/l] [select] |
|
Ahh, interesting. I have never shot myself in the foot with that caliber of bullet. Thank you for elucidating.
| [reply] |
|
Be aware. If you don't deliberately arrange the code in a weird order, it works just fine. That is, if your modules are loaded before the code that uses them, as in you have use Your::Module;, or even just ensure that the modules are compiled before the code that uses them, then the problem does not arise:
#!/usr/bin/perl
use warnings;
use strict;
package Foo;
sub new {
return bless {},shift;
}
sub hello {
print "hello";
}
package main;
sub new {
print "haha";
return;
}
my $a = new Foo;
$a->hello;
__END__
C:\test>junk2
hello
Just another example of the over-zealous promotion of a rare scenario, that by-the-by, provides clear and unambiguous diagnostics, into a "thou shalt not" that throws the baby out with the bath water. Just another justifiction.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
|
|
|
|
|
#!/usr/bin/perl
use warnings;
use strict;
use Foo; # some "forward declaration" syntax instead of looking for Fo
+o.pm?
sub new {
print "haha";
return;
}
my $a = new Foo;
$a->hello;
package Foo;
sub new {
return bless {},shift;
}
sub hello {
print "hello";
}
I couldn't find it under use in perlfunc. I was also trying use main::Foo; and use ::Foo; based on some ideas that popped into my head while reading about Packages in perlmod.
| [reply] [d/l] [select] |
|
Anything that unambiguously uses a package automatically declares a package, and so does a package Foo statement.
So you could do
package Foo;
package main; # or whatever package is the 'current' one
Which is probably the clearest way of doing it, or you can do something like:
$Foo::a=$Foo::a; # using $Foo::a twice will silence the 'used only on
+ce' warning
Note that fully specified package variables are exempt from 'strict "vars"' rules. Or you can declare a subroutine:
sub Foo::declare_package_Foo;
The same technique would work for anything else that unambiguously uses the Foo package.
| [reply] [d/l] [select] |
Re^4: Is it ok to mix functional and oo programming in one package?
by eyepopslikeamosquito (Archbishop) on Oct 18, 2007 at 21:52 UTC
|
| [reply] [d/l] |