perl

Scalar::Util::blessed() appears to return octets


When an object whose type is a non-ASCII name is passed to Scalar::Util::blessed(), it appears to return octets instead of a Perl string. I'm running ActiveState Perl v5.20.2 on Windows. Can someone please check whether this happens on any other platforms/versions? (Note that confess() displays the class name correctly for the check_self() call.)

use strict; use warnings;
use utf8;
use English;
use feature qw(unicode_strings);
use open qw(:std :utf8);

package MyClass {
    use strict; use warnings;
    use utf8;
    use feature qw(unicode_strings);
    use Carp ();
    use Scalar::Util ();

    sub new {
        my $class = $_[0];
        return bless( {}, $class );
    }
    sub check_class {
        my $class = $_[0];
        STDERR->print( "$class\n" );
        unless ( defined($class) && ref($class) eq '' 
               && $class->isa(__PACKAGE__) ) {
          Carp::confess( sprintf( "bad call to %s()", ( caller(1) )[3] ) );
        }
        return;
    }
    sub check_self {
        my $self = $_[0];
        check_class( Scalar::Util::blessed($self) );
        return;
    }
}

package MüClass {
    use strict; use warnings;
    use utf8;
    use Carp ();
    use Scalar::Util ();

    sub new {
        my $class = $_[0];
        return bless( {}, $class );
    }
    sub check_class {
        my $class = $_[0];
        STDERR->print( "$class\n" );
        Carp::confess( sprintf( "bad call to %s()", ( caller(1) )[3] ) )
            unless defined($class) && ref($class) eq '' 
                && $class->isa(__PACKAGE__);
        return $class;
    }
    sub check_self_1 {
        my $self = $_[0];
        return check_class( ref($self) );
    }
    sub check_self_2 {
        my $self = $_[0];
        my $class;
        $class = check_class( Scalar::Util::blessed($self) );
        return $class;
    }
    sub check_self_3 {
        my $self = $_[0];
        my $class = Scalar::Util::blessed($self);
        utf8::decode($class) unless utf8::is_utf8($class);
        return check_class($class);
    }
}

my $myclass = MyClass->new;
MyClass->check_class;
$myclass->check_self;
my $müclass = MüClass->new;
MüClass->check_class;
$müclass->check_self_1;
eval{ $müclass->check_self_2; };
STDERR->print($EVAL_ERROR) if $EVAL_ERROR;
$müclass->check_self_3;

Output:

MyClass  
MyClass  
MüClass  
MüClass  
MüClass  
bad call to MüClass::check_self_2() at D:\Batch/test-blessed.pl line 47.
        MüClass::check_class("M\x{c3}\x{bc}Class") called at D:\Batch/test-blessed.pl line 59  
        MüClass::check_self_2(MüClass=HASH(0x256d560)) called at D:\Batch/test-blessed.pl line 76  
        eval {...} called at D:\Batch/test-blessed.pl line 76  
MüClass

Solution

  • Looks to me like a bug in versions of Scalar::Util before 1.53.

    https://metacpan.org/release/PEVANS/Scalar-List-Utils-1.68/source/Changes#L115:

    1.53 -- 2019-10-24 10:41:12 [BUGFIXES] * Handle Unicode package names in Scalar::Util::blessed (GH #81)

    Try upgrading your Scalar-List-Utils or upgrade perl to 5.31.6 or better.