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

Hi all,

i wonder why B::Deparse shows __END__ as __DATA__:

karls-mac-mini:monks karl$ cat data.pl #!/usr/bin/perl __DATA__ karls-mac-mini:monks karl$ cat end.pl #!/usr/bin/perl __END__ karls-mac-mini:monks karl$ perl -MO=Deparse end.pl __DATA__ end.pl syntax OK karls-mac-mini:monks karl$ perl -MO=Deparse data.pl __DATA__ data.pl syntax OK

Please see also this:

karls-mac-mini:monks karl$ cat data_end.pl #!/usr/bin/perl __DATA__ __END__ karls-mac-mini:monks karl$ perl -MO=Deparse data_end.pl __DATA__ __END__ data_end.pl syntax Ok

Thank you very much for any hint and best regards, Karl

«The Crux of the Biscuit is the Apostrophe»

Replies are listed 'Best First'.
Re: Why shows B::Deparse __END__ as __DATA__?
by LanX (Saint) on Oct 11, 2014 at 10:44 UTC
    IIRC you'll only observe a subtle difference between __END__ and __DATA__ when including modules and trying to read from <DATA> .

    So your example doesn't show a bug (yet).

    Try B::Terse to see if there are any different OP codes involved.

    If yes, please send a bug report regarding B::Deparse

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

      Thanx LanX for your reply.

      "Latimer spent some time trying to explain in French the meaning of 'to call a spade a bloody shovel'...Colonel Haki listened intently, nodding his head and saying, 'Yes, I see it clearly know'..." (from "The Mask of Dimitrios" by Eric Ambler)

      What B::Terse shows me at a glance is:

      karls-mac-mini:monks karl$ perl -MO=Terse end.pl end.pl syntax OK

      OK, first try - looks like i need to RTFM.

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

        Donc tu veux que je l'explique en Francais??? ;)

        perldata documents the difference, you'll find many discussions on the matter in the monk archives.¹

        Maybe B::Concise is better suited to analyze the OP tree. ( If there is any difference, NB: B::Deparse can only analyze the OP tree!)

        I just noticed you didn't append any data after __DATA__ in your examples, but then optimization may influence the OP tree.

        Can't check myself while posting from Android... :)

        Salutations Rœlf

        (addicted to the Perl Programming Language and ☆☆☆☆ :)

        update

        ¹) https://www.google.com/search?q=__END__+__DATA__+site:www.perlmonks.org

      No.

      $ cat >a.pl print <DATA>; __END__ a b c $ perl a.pl a b c

      They're synonymous.

        Read perldata !

        Behavior under a package other than main:: differs significantly!

        Cheers Rolf

        (addicted to the Perl Programming Language and ☆☆☆☆ :)

        update

        would you mind reading the thread before spreading your theories?

Re: Why shows B::Deparse __END__ as __DATA__?
by LanX (Saint) on Oct 11, 2014 at 19:52 UTC
    So, had a look into B::Deparse and I can confirm that it doesn't even try to handle __END__ .

    As I expected it only tries to read the data from the <DATA> of the last package and always assumes that a __DATA__ line was leading.¹

    That's the corresponding code chunk

    # Print __DATA__ section, if necessary no strict 'refs'; my $laststash = defined $self->{'curcop'} ? $self->{'curcop'}->stash->NAME : $self->{'curstash'}; if (defined *{$laststash."::DATA"}{IO}) { print "package $laststash;\n" unless $laststash eq $self->{'curstash'}; print "__DATA__\n"; print readline(*{$laststash."::DATA"}); }

    Theoretically it's not that difficult to decide if there was a preceding __END__ or __DATA__ , one only needs to seek back.

    my $laststash = "main"; my $data=\*{$laststash."::DATA"}; $last = tell $data; seek $data,-20,1; # -20 is just a temporary hack for proof +of concept my $endline; $endline = readline($data) while tell $data < $last; print $endline; print <$data>; #package Test; # __DATA__ # data # data __END__ end end

    this will print

    __END__ end end

    and after uncommenting __DATA__

    __DATA__ # data # data __END__ end end

    The real issue is finding the real file handle, cause __END__ always belongs to *main::DATA no matter which package was used.

    This issue needs some testing and even more documentation, cause I'm not 100% sure how multiple __END__ or __DATA__ sections in different files are handled.

    I suppose (IIRC) that the last (current) __END__ dominates, but which filehandles are then even defined?

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

    ¹) could be called a bug!

Re: Why shows B::Deparse __END__ as __DATA__?
by ikegami (Patriarch) on Oct 12, 2014 at 02:41 UTC

    There's absolutely no difference between __END__ and __DATA__, just like there's absolutely no difference between for and foreach.

    $ perl -MO=Deparse -e'foreach (@a) { }' foreach $_ (@a) { (); } -e syntax OK $ perl -MO=Deparse -e'for (@a) { }' foreach $_ (@a) { (); } -e syntax OK
    $ perl -MO=Deparse -e'for (a(); b(); c()) { }' for (a(); b(); c()) { (); } -e syntax OK $ perl -MO=Deparse -e'foreach (a(); b(); c()) { }' for (a(); b(); c()) { (); } -e syntax OK

    Since there's no difference, Deparse has no idea which one was used in the source, so it uses whatever it finds most idiomatic.

      and here a real bug:

      lanx@nc10-ubuntu:/tmp$ cat end_pkg.pl print <DATA>; package TST; 1; __END__ end lanx@nc10-ubuntu:/tmp$ perl -MO=Deparse end_pkg.pl print <DATA>; package TST; '???'; end_pkg.pl syntax OK lanx@nc10-ubuntu:/tmp$ perl end_pkg.pl end lanx@nc10-ubuntu:/tmp$ perl -MB::Deparse -E 'say "$B::Deparse::VERSION +"' 0.83

      update
      took a look into current source of B::Deparse version 1.20 and it has the same code regarding __DATA__

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

        and here another related bug, B::Deparse appends the wrong __DATA__ from the used module, cause of package confusion.

        lanx@nc10-ubuntu:/tmp$ cat use_wrong.pl use wrongdata; print <DATA>; package TST; 1; __END__ end lanx@nc10-ubuntu:/tmp$ perl use_wrong.pl end lanx@nc10-ubuntu:/tmp$ cat wrongdata.pm package TST; 1; __DATA__ wrongdata lanx@nc10-ubuntu:/tmp$ perl -MO=Deparse use_wrong.pl use wrongdata; print <DATA>; package TST; '???'; package TST; __DATA__ wrongdata use_wrong.pl syntax OK

        Cheers Rolf

        (addicted to the Perl Programming Language and ☆☆☆☆ :)

        update

        see Re^2: Why shows B::Deparse __END__ as __DATA__? for explanation!