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

hai monks, Perl is a free, open source programming language
open function in perl takes arguments like
1.file handle
2.mode
3.filename
i want to redesign the open function ,is there any possibilty to design the open function in perl according to my convinience.


i mean if i call open function which module is called internally.which module i can perform modification so that i can design the open function for my convinience
thanks in advace,
regards,
singam

Replies are listed 'Best First'.
Re: design the open function
by davido (Cardinal) on May 10, 2006 at 07:10 UTC

    Use the subs pragma:

    use strict; use warnings; use subs qw/ open /; open(); sub open { print "Hello world!\n"; }

    Here is an excerpt from the Camel book, Programming Perl

    Overriding may be done only by importing the name from a module--ordinary predeclaration isn't good enough. To be perfectly forthcoming, it's the assignment of a code reference to a typeglob that triggers the override, as in *open = \&myopen. Furthermore, the assignment must occur in some other package; this makes accidental overriding through typeglob aliasing intentionally difficult. However, if you really want to do your own overriding, don't despair, because the subs pragma lets you predeclare subroutines via the import syntax, so those names then override the built-in ones:

    I'm not going to address whether this is actually a good idea, other than to say you ought to really really really think about other options first, especially if you care about writing maintainable code.

    Update: There's additional information on the subject in perlfaq7 and perlsub.


    Dave

      thanks Davido,
      but if i like to open a file inside that open subroutine.
      then it will become recursive function right.
      How to eliminate that error.

        Within the subroutine, call the fully qualified name for open: CORE::open( ....... ).

        CORE::open() will always refer to the original open. ....always, that is, unless you read in perlsub how to mess that up too. ;) (Hint: don't mess with CORE::open, without an extraordinarily good reason.)


        Dave

Re: design the open function
by jonadab (Parson) on May 10, 2006 at 12:02 UTC
    is there any possibilty to design the open function in perl according to my convinience

    I'm going to come right out and say what others have been trying to imply: You don't want to do that. Yes, it's possible, but it's not what you want to do. There are rare circumstances under which someone might want to do that, but it would be someone who knows Perl pretty well, and they wouldn't have to ask *how* to do it. If you have to ask how, it demonstrates that you do not know Perl well enough to understand all the implications of doing this, which implies that you do not want to do it, because the implications will catch you by surprise and cause you no end of trouble.

    The other thing that tells me you do not, in fact, want to do this is your use of the phrase "according to my convenience". Redefining builtin functions isn't a source of convenience; in fact, it's downright *inconvenient* (not because it's hard to do, but the other way around: it was made (a little bit) hard to do precisely because of the inconvenience it causes).

    Furthermore, your comments in this thread seem to indicate that you don't understand package namespaces, which is an important thing to understand before messing with the built-in portion of your main namespace.

    I'm not kidding, you really don't want to do this. This thread almost certainly has an XY Problem. I We don't know what you're trying to accomplish, but there's almost certainly a Much Better Way, and if you post a question about how best to do what you're really trying to do, it's very likely that someone will show you a way to do it that does not involve re-defining builtin functions. (Probably there's a module on the CPAN that does exactly what you're trying to accomplish anyhow...) That way will ultimately be much more convenient.


    Sanity? Oh, yeah, I've got all kinds of sanity. In fact, I've developed whole new kinds of sanity. Why, I've got so much sanity it's driving me crazy.
      I have a number of perl scripts which inturn contains a number of open functions.now, i need to set the environtment variable,according to the environment variable whether it is set or not.I have to open the file in encoding layer if environment variable is set.If not set , i have to do the normal way.

      It is time consuming to change in each and every file.
      how to do this, without modifying the previous scripts.

        Try this approach: (updated) First, add the following lines to one of your scripts, starting at approximately the second line of the script, to test my method:

        no warnings 'layers'; use open ':locale'; use warnings 'all';

        If that works, then test the following Perl one-liner on another one of your scripts. It will modifiy the script itself.

        perl -pi.bak -e "if( $. == 2 ) { $_ = q/no warnings 'layer';\n use ope +n ':locale';\nuse warnings 'all';\n$_/;}" myscript.pl

        ...where, after testing to make sure it didn't completely wreck "myscript.pl", you go ahead and run that on all the scripts you need modified. The effect will be to add the following line to the 2nd line of each script on which you run the command:

        no warnings 'layer'; # This squelches any warning due # to the open pragma not being able to find # a locale definition in your environment # variables. use open ':locale'; # set a default locale for all IO # in your script based on env vars. use warnings 'all';

        Please read documentation on the open pragma to understand what is at work here. And PLEASE test this on just one script first; I haven't tested it.


        Dave

        I'm not sure if I understand. If you have to open your files with different layers depending on an environment variable, then something like this should do the trick:

        open my $in, "<:$ENV{LAYER}", $infile or die $!; open my $out, ">:$ENV{LAYER}", $outfile or die $!; # ...

        Of course if you depend like that one an environment variable then you should take care of doing some validation: the above is meant as a minimal example...

        PS: it's clear that English is not your mother tongue, it's not mine either: so I suggest you take a deep breath and try to find a good wording to express your questions, because I bet I'm not the only one having difficulties to understand what you mean.

        I have a number of perl scripts which inturn contains a number of open functions.now... It is time consuming to change in each and every file.

        This is approximately the reasoning I guessed you were using. It's flawed reasoning, because it contains a false economy.

        For each script that you have, it will take you about 45 seconds to add an include or use line at the beginning (to pull in your custom function), run a search and replace (to turn open into mypackage::open or somesuch), and save, then you have to test each script, but probably everything will just work.

        If you do it the other way, it will take you 30 seconds to add the include or use line at the beginning that causes open to be redefined, and save, then you have to test each script. So you save fifteen seconds per script. However, there will probably be unforseen problems with some of the scripts that will cause weird bugs and result time spent debugging, which will more than eat up your saved seconds. What is worse, next month or next year when you try to add a feature to one of your scripts, and you descover that your changes don't quite do what you thought they should, you'll at first think your changes are wrong and waste time trying to debug that, only to discover that in fact it was your redefined open function that caused the problem. Then you'll have to revisit this issue, put the open function back the way it was, and do what you should have done.

        Do it right in the first place. Spend the extra fifteen seconds per script and do the search and replace. It will save you a lot of time.


        Sanity? Oh, yeah, I've got all kinds of sanity. In fact, I've developed whole new kinds of sanity. Why, I've got so much sanity it's driving me crazy.
Re: design the open function
by blazar (Canon) on May 10, 2006 at 09:46 UTC
    hai monks, Perl is a free, open source programming language

    Yes it is. Indeed other than davido's suggestion, you may modify the perl sources, which are freely available. I recommend you do so only if you have a very in-depth knowledge of {P,p}erl, but if you do, then you'll get a perl executable incompatible with the rest of the world, and such will be your code too. All in all I bet that if you had that kind of expertise, then you wouldn't ask this question - and everything in this thread suggests me that in fact you do not have it. So I feel forced to join davido and ask you: why on earth do you want to do so?

    PS: of course if you modify the sources, then you may submit a patch to perl; of course it will be accepted only if

    • it is backwards compatible;
    • it brings some real benefit.