Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First use of "binmode STDOUT, ':encoding(UTF-8)'" shows as a use statement in structure #311

Open
c-folsom opened this issue Dec 20, 2022 · 1 comment

Comments

@c-folsom
Copy link

When using "binmode" with ":encoding()" if the line of code is run then this line will show up as if it was a "use" statement and once as a normal statement line in the structure file. If it is not run then it does not show up as if it was a "use" statement. It does not matter what the file handle is or the encoding type. If "encoding" is not used then this does not happen, i.e. "binmode STDOUT, ':utf8';".

The main issue is that this will cause merge conflicts if one test does not run this line of code and the second test does. Then when merging the structures do not match. This can be seen with the code below:

sub foo {
   print "foo\n";
   binmode STDOUT, ':encoding(UTF-8)';
}
foo();

The structure then acts as if the "binmode" line was both a "use" statement and a normal line so the statement structure is [5, 3, 3, 3, 2, 3]. If we remove the call to foo() then the "binmode" line show up as a single statement line [2, 3].

I also noticed if "binmode" with "encoding" is used twice then only the first call will show up as a "use" statement plus a normal statement line. The second will then only show up as a normal statement line. For example if the file contained:

binmode STDIN, ':encoding(utf8)';
binmode STDOUT, ':encoding(UTF-8)';

This file would give the following structure:
{"subroutine":[[1,"BEGIN"]],"start":{"1":{"BEGIN":[{"time":null,"statement":2,"branch":null,"pod":null,"subroutine":null,"condition":null}]},"-1":{"__COVER__":[{"subroutine":1,"condition":null,"time":null,"statement":5,"branch":null,"pod":null}]}},"file":"f2.pl","statement":[1,2,1,1,1],"digest":"8374f104aa1d19561eeea886e144a687"}

The structure would also be the same if both "binmode" lines were identical:

binmode STDIN, ':encoding(utf8)';
binmode STDIN, ':encoding(utf8)';

I did noticed that if running this using the perl debugger the first call to "binmode" is run four times:

main::(f2.pl:1):        binmode STDIN, ':encoding(utf8)';
main::CODE(0x28c6560)(f2.pl:1): binmode STDIN, ':encoding(utf8)';
PerlIO::CODE(0x28c6560)(/path/to/PerlIO.pm:3):
3:      our $VERSION = '1.11';
PerlIO::CODE(0x28c6560)(/path/to/PerlIO.pm:6):
6:      our %alias;
PerlIO::CODE(0x28c6560)(/path/to/PerlIO.pm:29):
29:     1;
30:     __END__
main::CODE(0x28c6560)(f2.pl:1): binmode STDIN, ':encoding(utf8)';
main::CODE(0x28c6560)(f2.pl:1): binmode STDIN, ':encoding(utf8)';
PerlIO::import(/path/to/PerlIO.pm:10):
10:      my $class = shift;
@c-folsom
Copy link
Author

c-folsom commented Jan 6, 2023

Found a workaround for this issue. If including a use statement for "encoding()" then when "binmode" using "encoding()" is called for the first time it does not show up like a use statement:

use open ':encoding(UTF-8)';

binmode STDIN, ':encoding(utf8)';
binmode STDIN, ':encoding(utf8)';

This does not show a use statement for the first call of "binmode", statement structure [2,3,1,1,1].

I think what is happening here is when "binmode" or "open" are used with "encoding()" for the first time there is a use statement being used to include "encoding()", Devel::Cover then only sees the use statement and writes it to the structure file if the line that uses "encoding()" is called.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant