Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

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

by gamache (Friar)
on Oct 18, 2007 at 20:02 UTC ( [id://645836]=note: print w/replies, xml ) Need Help??


in reply to Re^2: 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?

my $obj = new Foo;

This syntax introduces weird parser ambiguities that often depend on the order of compilation. Stick with Foo->new().

According to the Camel Book beside me, method invocation using the METHOD CLASS_OR_INSTANCE LIST form is exactly equivalent to CLASS_OR_INSTANCE->METHOD (LIST) form.
  • Comment on Re^3: Is it ok to mix functional and oo programming in one package?

Replies are listed 'Best First'.
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).

      I don't think there's any guessing. If there is, let me know so I can fix this.

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.
      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.

      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.

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

    Avoiding the:

    my $obj = new Foo;
    indirect object syntax is routine Perl style advice. See, for example:

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://645836]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-24 15:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found