Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

__END__ without __BEGIN__?

by ktross (Deacon)
on Mar 29, 2005 at 20:49 UTC ( [id://443253]=perlquestion: print w/replies, xml ) Need Help??

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

Why does perl have and __END__ token, but not a __BEGIN__ token?
Why are we permited to store data only at the end of a file?
Is it unreasonable to want to attach runnable perl code to the end of a file?

What I mean is, why is this forbidden:

b@d __BEGIN__ print 'ignore b@d'; die;
but this allowed:
print 'ignore b@d'; die; __END__ b@d
There is a defined BEGIN{} subroutine that is the first thing run when a perl script is called, but perl decides that running it is un-safe if there are syntax errors anywhere in the file. For example:
b@d BEGIN{ print 'ignore b@d'; die; }
Does not run.

Am I missing something?

update:perl -x is close enough for me =)

Replies are listed 'Best First'.
Re: __END__ without __BEGIN__?
by merlyn (Sage) on Mar 29, 2005 at 20:52 UTC
    Assuming this isn't a troll...

    Are you presuming the Perl compiler is psychic? How would it know that "b@d" at the beginning is to be skipped over? The current compiler is single pass... only once over the input file (which is why you can pipe a script from STDIN).

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      No troll, just curious. Still...Even presuming the compiler is not phsycic, why can't you have a tag that says "forget what you have seen up to this point", when you have one that says "ignore the rest of the file?"
        You could probably do that (more or less) using source filters.

        use Filter::ignore-until-BEGIN-token; b@d __BEGIN__ print 'ignore b@d'; die;

        Now all that has to be done is writing the Filter::ignore-until-BEGIN-token-filter.

        We will leave that as an exercise for the reader. ;-)

        CountZero

        "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

        At first glance it seems that this would be something easily accomplished with a source filter. Of course it's entirely possible I'm wrong since you would then be asking it to forget that it loaded the source filter.


        ___________
        Eric Hodges
Re: __END__ without __BEGIN__?
by moot (Chaplain) on Mar 29, 2005 at 21:26 UTC
    For one thing, it would make the compiler slower and less stable. Consider:
    BEGIN { my $var = do_some_processing(); } __BEGIN__ # start of real processing.. but the compiler has already processed th +e BEGIN block! # ..real code here..
    The compiler would have to forget everything it did in the BEGIN block, and if there were side effects (for example, writing to files), all of that would have to be undone.

    I suppose your hypothetical __BEGIN__ tag could cause the compiler to simply ignore everything until such a tag is seen.. but what if the tag doesn't exist? the compiler would have to either re-read the file (breaking STDIN, as per merlyn's comment Re: __END__ without __BEGIN__? above), or would have to store a potentially enormous file (plus dependencies) in memory before compilation could truly begin*. This issue doesn't exist with __END__ because the compiler can fall off the end of the file and thus not need to see an __END__ tag.

    Of course this could all be complete hooey. Larry may have just left out __BEGIN__ because to include it would be extra work ;)

    * - It might do this already, but without the __BEGIN__ tag compilation can begin as soon as perl figures out it has something to work with, which is at least potentially faster.

    Update: changed 'more unstable' to 'less stable' - did not mean to imply the compiler was already unstable ;)

      the compiler would have to either re-read the file (breaking STDIN, as per merlyn's comment
      Why is this an argument? If "this feature can't be used on STDIN", why does perl have a -i option? That can't be applied to STDIN either - and -i is then silently ignored. If one were to implement such a __BEGIN__ token (not that I'm advocating this), it would be rather simple to decide what should be done in case of a program passed from STDIN. Heck, one can't seek the DATA file handle from a program found on STDIN either.
      would have to store a potentially enormous file (plus dependencies) in memory before compilation could truly begin
      Considering that the optree + perl binary + data for perl itself usually measures at least a couple of megabytes, this isn't a real argument, is it? While it's not impossible to create a file of a few megabytes that, when compiled, actually takes less memory, it's not something to worry about.

      I think the only reason this feature isn't there is because it's not useful enough to implement it. Besides, there's already 'perl -x'. Breaking STDIN and "takes too much memory" aren't real arguments.

        I think the only reason this feature isn't there is because it's not useful enough to implement it.

        Maybe you should have read the part of my comment where I said that maybe the feature wasn't implemented because it was too much work.

Re: __END__ without __BEGIN__?
by gaal (Parson) on Mar 30, 2005 at 14:42 UTC
    perl does have a __BEGIN__ token. You just have to start it with the -x option.

    % perl -x Here there be data. More of it. __BEGIN__ #!/usr/bin/perl -wl use strict; # yeah. print "Hello, world."; __END__ ^D Hello, world.
Re: __END__ without __BEGIN__?
by NateTut (Deacon) on Mar 30, 2005 at 18:10 UTC
    ‘Everything that has a beginning, has an end’

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2024-04-25 22:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found