in reply to Re^3: Is it ok to mix functional and oo programming in one package?
in thread Is it ok to mix functional and oo programming in one package?

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.

Replies are listed 'Best First'.
Re^5: Is it ok to mix functional and oo programming in one package?
by gamache (Friar) on Oct 18, 2007 at 20:41 UTC
    Ahh, interesting. I have never shot myself in the foot with that caliber of bullet. Thank you for elucidating.

      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.
        If you don't deliberately arrange the code in a weird order, it works just fine.

        In larger programs which are not small tests cut down for didactic purposes, do you always know when exactly when everything gets declared? How about in programs that use Module::Pluggable or another extension mechanism?

        I've debugged this problem more than once. (I've also debugged the $_ gets localized implicitly except when it doesn't.) Sure, it's not always a problem... but when it is, it's not always as obvious as anyone would like.

        Ah, but wait, you didn't write
        hello $a;
        Why's that? It works ;-)

Re^5: Is it ok to mix functional and oo programming in one package?
by goibhniu (Hermit) on Oct 19, 2007 at 20:46 UTC

    Is there some way to do this:

    #!/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.


    I humbly seek wisdom.
      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.