develooper Front page | perl.perl5.porters | Postings from October 2013

[perl #119499] $! returned with UTF-8 flag under UTF-8 locales only under 5.19.2+

Thread Previous
From:
Victor Efimov via RT
Date:
October 16, 2013 11:28
Subject:
[perl #119499] $! returned with UTF-8 flag under UTF-8 locales only under 5.19.2+
Message ID:
rt-3.6.HEAD-26210-1381922882-779.119499-15-0@perl.org
On Tue Oct 15 14:59:45 2013, public@khwilliamson.com wrote:
> What you want is for $! to work like it's in 'use bytes'.  I can change 
> the patch so that it checks for 'use bytes' and if within that scope 
> returns without the utf8 flag set.  You would then just need to add a 
> 'use bytes' to get it to work the same way it always has.
> 
> There are people who would disapprove of ever using bytes, which means 
> they think the behavior you want is wrong.  I'm not one of them.  I 
> think that 'use bytes' should be rare, mostly used in testing, but it 
> sometimes is the easiest, clearest way of getting at the bytes that 
> comprise a UTF-8-encoded character.  utf8::encode() can be used for 
> that, but destroys its argument and I think its name is much less clear 
> than 'use bytes'.
> 
> I have tested doing this, and it works.


New behaviour looks sane to me. It's probably thay way it's supposed to
work from beginning. Main problem solved (when $! sometimes returned
characters, sometimes bytes).

There were comments that enabling new behaviour in lexical scope is not
good and danger (but you stated that it's probably OK). We enabled it by
default, and users now can switch to *old* behaviour in *lexical* scope
(with use bytes or use locale). I think arguments that lexical scope is
not good can apply here too.

The big problem that I see now is backward compatibility. Any existing
code that uses $! is probably broken.

Users will have to fix it with use locale/use bytes.

Few examples that I found (where filenames are concatenated with $!):

====
Fild::Temp
        unless ($!{EEXIST}) {
          ${$options{ErrStr}} = "Could not create temp file $path: $!";
          return ();
        }

File::Find
	    unless (defined $topnlink) {
		warnings::warnif "Can't stat $top_item: $!\n";
		next Proc_Top_Item;
	    }

LWP::UserAgent
	my @stat        = stat($tmpfile) or die "Could not stat tmpfile
'$tmpfile': $!";
	or die "Cannot rename '$tmpfile' to '$file': $!\n";

====

Note, that if filename here contains non-ASCII characters and is binary
string, merging it with character string $! would produce broken result.

Even if filename is ASCII, it would break old behaviour when die
exception printed to STDERR.

If filename is character string, that code did not work correctly
previously.

Another issue that there is POSIX::strerror, and IMHO it should behave
just like $! for consistency (i.e. produce different things depending on
lexical scope). POSIX::strerror is pure perl.



---
via perlbug:  queue: perl5 status: open
https://rt.perl.org:443/rt3/Ticket/Display.html?id=119499

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About