Mystery Line in Proc Input in Perl 6

Here's something odd; not sure if it's a bug or just something I don't understand.

I have a utility on my system called k8temp which reports the temperature of the CPUs. It reports it in Celsius, so I thought I'd write a little wrapper that converts the temps to Fahrenheit. k8temp outputs one line per core, so on my dual-core system, the output looks like this:

abaugher@bannor> k8temp
CPU 0 Core 0 Sensor 0: 38c
CPU 0 Core 1 Sensor 0: 38c
abaugher@bannor>

And piping it to a hex dump looks like this:

abaugher@bannor> k8temp|hd
00000000: 43 50 55 20, 30 20 43 6f, 72 65 20 30, 20 53 65 6e ;CPU 0 Core 0 Sen
00000010: 73 6f 72 20, 30 3a 20 33, 39 63 0a 43, 50 55 20 30 ;sor 0: 39c.CPU 0
00000020: 20 43 6f 72, 65 20 31 20, 53 65 6e 73, 6f 72 20 30 ; Core 1 Sensor 0
00000030: 3a 20 33 38, 63 0a                                 ;: 38c.

So there are definitely just two lines there, right? But when I run my script, I get three lines: the two expected lines and then a blank one. Here it is:

#!/usr/bin/env perl6
use v6;

sub MAIN() {          
    my $p = run 'k8temp', :out;
    for $p.out.lines {
        if / (.*?) (\d+) c / {
            say  [~] $0, round($1*9/5+32), "°";
        } else {
            say 'Mystery line: ',$_;
        }
    }
}

And the output:

abaugher@bannor> ./k8temp.p6
CPU 0 Core 0 Sensor 0: 108°
CPU 0 Core 1 Sensor 0: 106°
Mystery line: 
abaugher@bannor> ./k8temp.p6|hd
00000000: 43 50 55 20, 30 20 43 6f, 72 65 20 30, 20 53 65 6e ;CPU 0 Core 0 Sen
00000010: 73 6f 72 20, 30 3a 20 31, 30 39 c2 b0, 0a 43 50 55 ;sor 0: 109°.CPU
00000020: 20 30 20 43, 6f 72 65 20, 31 20 53 65, 6e 73 6f 72 ; 0 Core 1 Sensor
00000030: 20 30 3a 20, 31 30 34 c2, b0 0a 4d 79, 73 74 65 72 ; 0: 104°.Myster
00000040: 79 20 6c 69, 6e 65 3a 20, 0a                       ;y line: .

So the for loop is running three times, even though the subprogram only outputs two lines, and the value of $_ the third time through is the empty string. This will require more investigation. Am I missing something obvious here?

Update: I tried a couple things. First, slurping the output of the process shows no third line:

#!/usr/bin/env perl6
use v6;

sub MAIN() {          
    my $p = run 'k8temp', :out;
    print $p.out.slurp-rest;
}
# results
abaugher@bannor> ./k8.p6|hd 
00000000: 43 50 55 20, 30 20 43 6f, 72 65 20 30, 20 53 65 6e ;CPU 0 Core 0 Sen
00000010: 73 6f 72 20, 30 3a 20 34, 31 63 0a 43, 50 55 20 30 ;sor 0: 41c.CPU 0
00000020: 20 43 6f 72, 65 20 31 20, 53 65 6e 73, 6f 72 20 30 ; Core 1 Sensor 0
00000030: 3a 20 33 39, 63 0a                                 ;: 39c.

Then using .lines instead:

#!/usr/bin/env perl6
use v6;

sub MAIN() {          
    my $p = run 'k8temp', :out;
    my @l = $p.out.lines;
    @l.perl.say;
}
# results
abaugher@bannor> ./k8.p6
["CPU 0 Core 0 Sensor 0: 42c", "CPU 0 Core 1 Sensor 0: 40c", ""]<>

So .lines() appears to be adding a third element. Now to figure out why.

8 Comments

Hi Aaron,

I noticed this as well, but I must've forgotten to report a bug for it in RT. I've corrected that mistake: https://rt.perl.org/Ticket/Display.html?id=125796

Please feel free to drop by #perl6 on Freenode and chat with us about your Perl 6 experiences! We can help out with issues like this.

-Rob

It looks like `k8temp` last byte is a "\n" (0x0a).
If lines is implemented as a simple split, this seems to be an expected behavior.

The weird thing is that the docs ( http://docs.perl6.org/type/Str#routine_lines ) seems to say that the ending newline shouldn't add an extra element to the return list


"a\n".lines.elems; # 1

Looking into it, it appears there is a different logic in setting EOF between getting a handle from a file, or from a process. The latter appears to be setting EOF too late, hence the extra empty line.

Determining cause of action now...

Tobias Leich went ahead and fixed the bug today!

Leave a comment

About Aaron Baugher

user-pic I'm a programmer and Unix sysadmin who uses Perl as much as possible, operating from the Midwest USA. To hire me for sysadmin or programming work, contact me at aaron.baugher @ gmail.com.