Beefy Boxes and Bandwidth Generously Provided by pair Networks vroom
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Creating modules with OO and functional interfaces.

by BazB (Priest)
on May 14, 2002 at 11:29 UTC ( #166417=perlquestion: print w/ replies, xml ) Need Help??
BazB has asked for the wisdom of the Perl Monks concerning the following question:

How would I go about creating a module that uses both OO and functional interfaces?

I tend to supply named arguments, and I get an error warning that there is an odd number of arguments in a hash assignment if I use a subroutine expecting $self as it's first argument.

I wouldn't think checking that the first argument is a reference is a solution - making pass-by-reference awkward is a Bad Thing :)

Below is a sample of _rough_ code that will only work as OO - how can it be transformed to work as a functional or OO module (like CGI.pm, for example - which I can't figure out :-) ).

package Foo; # use Modules; # set up @EXPORT, @EXPORT_OK etc for functional interface sub new { my $class = shift; my $self = {}; bless ($self, $class); } sub print_args { my $self = shift; my %args = @_; print $args{'foo'}, $args{'bar'}, "\n"; } package Bar; $obj = Foo->new(); $obj->Foo::print_args(foo => "Perl", bar => "Monks"); exit;
Cheers.

BazB

Comment on Creating modules with OO and functional interfaces.
Download Code
Re: Creating modules with OO and functional interfaces.
by ariels (Curate) on May 14, 2002 at 11:42 UTC

    CGI has this feature; it seems to live in the function ``<samp>self_or_default</samp>'' and maybe also ``<samp>self_or_CGI</samp>'' (both in the main <samp>CGI.pm</samp> file). You might examine its implementation -- it checks that the first argument is a reference, or that it ``isa-CGI'' (the first test is probably just optimizing for the common case).

Re: Creating modules with OO and functional interfaces.
by broquaint (Abbot) on May 14, 2002 at 11:58 UTC
    This sort of thing is generally discouraged in the world of OO where a consistent interface to the class is fairly key[1]. The mixing of a procedural[2] interface with class/object methods is rather counter-intuitive (where's my object state kept?!?). If you look at the source of CGI you can see it implements this mixing of styles by using a 'magical' method called self_or_default() which basically gets around the fact that a method is being called as a function. However if you're deadset on implementing both styles, then perl's certainly the language to do it in ;-) Check out the code for the self_or_default() method in CGI for some pointers on how to do this (it basically checks whether it's first argument is a reference to a CGI object or not and does the right thing).
    HTH

    _________
    broquaint

    [1] there's an interesting debate on this topic here between TheDamian and tilly
    [2] not functional, for functional + OO programming check out Haskell or OCaml

Re: Creating modules with OO and functional interfaces.
by particle (Vicar) on May 14, 2002 at 12:39 UTC
    CGI is a complex module for an example of providing OO and functional interfaces. check out Ben Tilly's ReleaseAction for a consise example.

    ~Particle *accelerates*

Re: Creating modules with OO and functional interfaces.
by cfreak (Chaplain) on May 14, 2002 at 13:22 UTC

    Even though I agree with the general feeling in this thread that its not a good idea™. You could check to see if $self is a reference and if not use it as the first argument.

    Hope that helps
    Chris

    Some clever or funny quote here.
Re: Creating modules with OO and functional interfaces.
by chromatic (Archbishop) on May 14, 2002 at 14:50 UTC
    You could say:
    my $self; $self = shift if (UNIVERSAL::isa( $_[0], 'My::Object' );
    I'd rather see a procedural interface that uses a default singleton object. Under the hood, it's using the OO interface, but the actual object is hidden from users, if that's necessary.
Re: Creating modules with OO and functional interfaces.
by Anonymous Monk on May 14, 2002 at 21:15 UTC
    In addition to chromatic's suggestion you might want to check how many arguments you got. If you also got an odd number of arguments then you (probably) got the object.

    Needless to say, these methods are not perfect. I too advice against it.

    -Anomo

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://166417]
Approved by coreolyn
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (11)
As of 2014-04-23 22:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (556 votes), past polls