Overload stringification and the utf8 flag

overloading, perl, stringification, utf-8

Solution

Overloaded stringification can return a different string every time it's called, so you're trying to find the storage format of a string that doesn't even exist yet. When you stringify the object, the UTF8 flag of the reference is updated to reflect the UTF8 of the stringified object.

`"".$t` would also work where you used `say $t;`.

Problem

There is something I don't understand about overloading stringification and how it interacts with the utf8 flag. For example the following code prints: ``` n is utf8 at ./test_stringify_utf8.pl line 46. $t->{name} is utf8 at ./test_stringify_utf8.pl line 47. t is not utf8 at ./test_stringify_utf8.pl line 48. Derviş t is utf8 at ./test_stringify_utf8.pl line 50. ``` If I remove `say $t`, the last line of output would also be `t is not utf8` ``` #!/usr/bin/env perl use utf8; use Encode qw/is_utf8/; use strict; use Modern::Perl '2013'; package Test; use strict; sub new { my ($class, $name) = @_; my $self = { name => $name }; bless $self, $class; return $self; } BEGIN { my %OVERLOADS = (fallback => 1); $OVERLOADS{'""'} = 'to_string'; use overload; overload->import(%OVERLOADS); } sub to_string { shift->{name} } package main; my $n = "Derviş"; my $t = Test->new($n); binmode STDOUT, ":utf8"; is_utf8($n) ? warn "n is utf8" : warn "n is not utf8"; is_utf8($t->{name}) ? warn '$t->{name} is utf8' : warn '$t->{name} is not utf8'; is_utf8($t) ? warn "t is utf8" : warn "t is not utf8"; say $t; is_utf8($t) ? warn "t is utf8" : warn "t is not utf8"; ```

Original source