http://qs321.pair.com?node_id=142637

mirg drol has asked for the wisdom of the Perl Monks concerning the following question:

I'm not very good at Perl (yet, i hope) and i was wondering if there's a way to create a sub that behaves like a built-in function.

This is my situation:

I have a module "global" in which a sub "compress" is defined. I use this module from the main package, and my program calls other modules at runtime. Is there a way to make the "compress" behave like a built-in function so that i don't have to use the "global" module from the called modules?

It uses different files:

- GLOBAL.pm: in which the compress sub is stored - script.pl: the main script - module_a.pm: some random module which uses compress - module_b.pm: etc.

I guess i have to use the Exporter module in some way, but that only seems to let a package that uses the "global" module.

Is this a 'correct' way to program or is it morally wrong and should i just use "GLOBAL->compress" instead of trying to call it with "compress" each time?

Thanks in advance! ;]

Replies are listed 'Best First'.
Re: Create a built-in-like sub?
by Juerd (Abbot) on Feb 01, 2002 at 09:16 UTC
    perldoc Exporter
    use base 'Exporter' our @EXPORT = qw(compress);

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

      I can't get that to work in my script. ;[ If i "require" a module from my main script, that module can't reach "compress" by simply calling "compress", only by calling "GLOBAL->compress". This is my test setup:

      main.pl
      #!/usr/bin/perl -w use GLOBAL; compress "main\n"; require "MODULE.pm"; MODULE->test;

      GLOBAL.pm
      package GLOBAL; use base 'Exporter' our @EXPORT = qw(compress); sub compress { print shift; } 1;
      MODULE.pm
      package MODULE; sub test { compress "test\n"; } 1;
      Did i just do something wrong is it impossible to use "compress" like this?
        Just as a note, your module should look like (at least in 5005_03):
        package GLOBAL use 'Exporter'; @ISA = qw(Exporter); #not always needed, but usually a good practice @EXPORT = qw(compress); ... 1; package MODULE use GLOBAL; use Exporter; @ISA = qw(Exporter); #again, usually a good practice. @EXPORT = qw(test); sub test { compress "test\n"; } 1;
        I may be incorrect in the new perl 5.6+ world since I'm still using 5.005_03. The only reason I added the use statement to the MODULE package is to make sure that the sub compress is pushed into it.

        Hope this helps, but YMMV.

        Theodore Charles III
        Network Administrator
        Los Angeles Senior High
        4650 W. Olympic Blvd.
        Los Angeles, CA 90019
        323-937-3210 ext. 224
        email->secon_kun@hotmail.com

        First, there is an error in GLOBAL.pm

        package GLOBAL; use base 'Exporter'
        is missing ';'
        use base 'Exporter';
        our @EXPORT = qw(compress); sub compress { print shift; } 1;

        Second, add use GLOBAL; to MODULE.pm

        package MODULE; use GLOBAL; sub test { compress "test\n"; } 1;



        HTH,
        Charles K. Clarkson
        Exporting (through Exporter or otherwise) comes in two parts. The code to export needs to declare what it will export. That's what using Exporter and populating @EXPORT or @EXPORT_OK does for you.

        The code that wants to import also must do something -- namely, asking the other code to import stuff. If you require MODULE, you need to call MODULE->import(). If you use MODULE, Perl will call import() automatically.

        Where did import() come from in MODULE? It came from using Exporter. If you'd require()d Exporter, you'd have had to call Exporter->import().

        Does that help?

Re: Create a built-in-like sub?
by Biker (Priest) on Feb 01, 2002 at 09:59 UTC

    It is not to my knowledge any way to let your Global.pm module "become a part of Perl", if that is what you want. Any piece of code that needs anything from your Global.pm will have to

    use Global.pm
    or require Global.pm "Livet är hårt" sa bonden.
    "Grymt" sa grisen...

Re: Create a built-in-like sub?
by    (Sexton) on Feb 01, 2002 at 20:47 UTC

    I found it to be a rather steep learning curve to learn the Perl Module concept. Then I found it to be an even steeper learning curve to understand the Perl OO modules.

    Nevertheless, I strongly recommend you to take the time necessary to learn the OO module programming. You will be rewarded for your efforts.

    The white hole.

Re: Create a built-in-like sub?
by dragonchild (Archbishop) on Feb 11, 2002 at 13:30 UTC
    While the question was answered, there's also the point of using prototypes to allow for the bareword function call. (You were under use strict, right?) That would allow for you to use compress() as a bareword and have it "behave appropriately".

    I think this was a 5.6+ feature. For what you go, I would write it as such:

    sub compress ($) { my $val = shift; # Do stuff with $val }
    If you wanted it to handle an array, then some number of other values (sorta like push) ...
    sub compress (\@@) { my $array = shift; my @values = @_; # Do stuff with the listref $array and the list of scalars @values }
    And, there are symbols for pretty much everything else you'd want to do.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.