Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.98k stars 560 forks source link

incompatibility of package-block and __DATA__ #22613

Open happy-barney opened 1 month ago

happy-barney commented 1 month ago

When using package block syntax and __DATA__ in single file, __DATA__ doesn't belong to package but to the main.

__DATA__ documentation states:

Text after __DATA__ may be read via the filehandle "PACKNAME::DATA",
    where "PACKNAME" is the package that was current when the __DATA__ token
    was encountered.

Technically it is correct, __DATA__ token is not specified inside package block (ie, package block prevents usage of __DATA__) But with code like in example that may be misleading. It may also harm adoption of syntax.

Example:

use strict;
use warnings;

package Foo {
    print while <DATA>;
}

__DATA__
hello
world

Output

Name "Foo::DATA" used only once: possible typo at example.pl line 7.
readline() on unopened filehandle DATA at example.pl line 7.

All Perls v5.12 .. v5.40 are affected.

Proposal:

a) support __DATA__ inside package block (ie, it will be treated as } as well b) treat insignificant content following } as content still belonging to the latest package block

Tux commented 1 month ago

I do not see that warning when using __DATA__, but I do see it when using __END__

mauke commented 1 month ago

I get

hello
world

as expected.

happy-barney commented 1 month ago

@mauke @Tux ouch, oops, I mentioned package block and typed example without it :-( ... editing issue

mauke commented 1 month ago

That is working as expected. The whole point of the package Foo { ... } syntax is that everything outside the braces is not part of the Foo package.

happy-barney commented 1 month ago

@mauke that I know, I mentioned that in technically part.

I also mentioned possible confusions and fact, that there is no alternative to attach __DATA__ to package except of old package syntax

Leont commented 1 month ago

there is no alternative to attach DATA to package except of old package syntax

I get that you might not like that aesthetically, but when is that a practical problem?

happy-barney commented 1 month ago

@Leont bad wording, likely to confuse

rest is only convenience - forcing inconsistent syntax across code base or, in case of class, weird syntax for class (especially if there is still hope of increasing usage of Perl)

iabyn commented 1 month ago

On Fri, Sep 20, 2024 at 01:51:45AM -0700, Branislav Zahradník wrote:

When using package block syntax and __DATA__ in single file, __DATA__ doesn't belong to package

Example:

use strict;
use warnings;

package Foo;

print while <DATA>;

__DATA__
hello
world

Output


Name "Foo::DATA" used only once: possible typo at example.pl line 7.
readline() on unopened filehandle DATA at example.pl line 7.

That example doesn't produce the output shown. I'm guessing the example was supposed to include a package block,

package Foo {
    print while <DATA>;
}

which does produce the output you show.

Proposal:

a) support __DATA__ inside package block (ie, it will be treated as } as well

Absolutely not. DATA is currently straightforward and predictable. Why on earth would you want to start including special-cased tricksy parsing? Then you end up with a whole can of worms. What about nested packages, possibly intermixed with other blocks?

b) treat insignificant content following } as content still belonging to the latest package block

Again, no, for the same reasons.

I can't see that this is a problem which needs fixing. The point of a block-scoped package declaration is that at some point in the file, you want to revert to the previous package. If you want the new package to be in scope to the end of the file, including the DATA token, then just leave the block off.

-- Wesley Crusher gets beaten up by his classmates for being a smarmy git, and consequently has a go at making some friends of his own age for a change. -- Things That Never Happen in "Star Trek" #18

shlomif commented 1 month ago

In addition, I'd like to note I feel __DATA__ is too abused and overused. I recommend using here-docs or https://metacpan.org/pod/File::ShareDir rather than the global-variable-like-*DATA

happy-barney commented 1 month ago

@shlomif too doesn't mean that its usage isn't advocated as well

Tux commented 1 month ago

In addition, I'd like to note I feel __DATA__ is too abused and overused. I recommend using here-docs or https://metacpan.org/pod/File::ShareDir rather than the global-variable-like-*DATA

I wholeheartedly disagree. I use __DATA__ and __END__ a lot and I have never in my life used File::ShareDir nor did I ever feel the need for that.

Main reason is that scripts with __END__/__DATA__ hold that data within and are easy to copy to other hosts whereas external files need to be copied seperately with all possible isseus.

Here-docs are file for a single-use short piece of data, but when dealing with a list or longer data structures or text pieces to apply tests to (like: does this parse), here-docs only blur the code

My € 2.00

haarg commented 1 month ago

Everything here is working as expected, and I don't think there's anything worth changing. __DATA__ is inherently a file-based feature, and trying to make it interact with inner lexical scopes isn't going to work well. class isn't any different from package here, and can be written without an enclosing block.

If you need a block of data inside a scope, you can use a heredoc.

happy-barney commented 1 month ago

@haarg I will repair your sentence: "Everything here is working as implemented", because this issue is about to change "as expected".

haarg commented 1 month ago

No, I chose my words intentionally. Based on how these features work, doing something other that how they work right now would be very strange.