Skip Menu |

This queue is for tickets about the Sub-Quote CPAN distribution.

Report information
The Basics
Id: 122698
Status: resolved
Priority: 0/
Queue: Sub-Quote

People
Owner: Nobody in particular
Requestors: MAUKE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.004000
Fixed in: 2.006006



Subject: Sub::Quote breaks with charnames, Function::Parameters
Sub::Quote tries to copy runtime %^H settings from the point of call of quote_sub into the compilation environment of the quoted code. This breaks all modules that put references in %^H (because it stringifies them). In case you're wondering "but who would do that?", Function::Parameters and charnames are among the affected modules. The latter even says (see https://metacpan.org/pod/charnames#CUSTOM-TRANSLATORS): Show quoted text
> The mechanism of translation of \N{...} escapes is general and not hardwired into charnames.pm. A module can install custom translations (inside the scope which uses the module) with the following magic incantation:
Show quoted text
> sub import { > shift; > $^H{charnames} = \&translator; > }
I.e. putting coderefs into %^H is an official Perl interface. Example using Function::Parameters: $ cat try2.pl #!perl use strict; use warnings; use Sub::Quote qw( quote_sub ); use Function::Parameters 2.001_001; my $subref = quote_sub 'return'; $subref->(); __END__ $ perl try2.pl Eval went very, very wrong: 1: { 2: my $_QUOTED = ${$_[1]->{"\$_QUOTED"}}; 3: my $_UNQUOTED = ${$_[1]->{"\$_UNQUOTED"}}; 4: package main; 5: $$_UNQUOTED = sub { 6: ($_QUOTED,$_UNQUOTED) if 0; 7: # BEGIN quote_sub PRELUDE 8: package main; 9: BEGIN { 10: $^H = 133090; 11: ${^WARNING_BITS} = "UUUUUUUUUUUUUUUU\025"; 12: %^H = ( 13: "Function::Parameters/config" => "HASH(0x8eee090)", 14: ); 15: } 16: # END quote_sub PRELUDE 17: return }; 18: } 19: 1; Function::Parameters: internal error: $^H{'Function::Parameters/config'} not a hashref: HASH(0x8eee090) at (eval 6) line 17. at try2.pl line 8. Example using charnames: $ cat try.pl #!perl use strict; use warnings; use Sub::Quote qw( quote_sub ); print "\N{DEGREE SIGN}_\N{DEGREE SIGN}\n"; my $subref = quote_sub 'print "\N{INVERTED EXCLAMATION MARK}Hola, mundo!\n"'; $subref->(); __END__ $ perl try.pl °_° Eval went very, very wrong: 1: { 2: my $_UNQUOTED = ${$_[1]->{"\$_UNQUOTED"}}; 3: my $_QUOTED = ${$_[1]->{"\$_QUOTED"}}; 4: package main; 5: $$_UNQUOTED = sub { 6: ($_QUOTED,$_UNQUOTED) if 0; 7: # BEGIN quote_sub PRELUDE 8: package main; 9: BEGIN { 10: $^H = 133090; 11: ${^WARNING_BITS} = "UUUUUUUUUUUUUUUU\025"; 12: %^H = ( 13: "charnames_full" => 1, 14: "charnames_stringified_ords" => "", 15: "charnames_name_aliases" => "HASH(0x89c5020)", 16: "charnames_loose" => 0, 17: "charnames_stringified_names" => "", 18: "charnames" => "CODE(0x8a1b840)", 19: "charnames_ord_aliases" => "HASH(0x89a83e0)", 20: "charnames_inverse_ords" => "HASH(0x89c5600)", 21: "charnames_short" => 1, 22: "charnames_stringified_inverse_ords" => "", 23: "charnames_scripts" => "", 24: ); 25: } 26: # END quote_sub PRELUDE 27: print "\N{INVERTED EXCLAMATION MARK}Hola, mundo!\n" }; 28: } 29: 1; Undefined subroutine &main::CODE(0x8a1b840) called at (eval 6) line 27. at try.pl line 8.
Constant overloads also have this issue. There are two sides to this. First is that the references are no longer available at the time quote_sub is called. The second is that even if ref hints are provided explicitly (rather than being retrieved from caller) they can't be installed properly. There is a todo test for the second issue at t/hints.t line 172. I'm not sure the best way to handle this. There are many cases where the current handling is helpful, but it can also cause issues that wouldn't exist if it didn't try to copy the hints.
On Thu Aug 03 09:15:41 2017, haarg wrote: Show quoted text
> Constant overloads also have this issue. > > There are two sides to this. First is that the references are no > longer available at the time quote_sub is called. The second is that > even if ref hints are provided explicitly (rather than being retrieved > from caller) they can't be installed properly. There is a todo test > for the second issue at t/hints.t line 172. > > I'm not sure the best way to handle this. There are many cases where > the current handling is helpful, but it can also cause issues that > wouldn't exist if it didn't try to copy the hints.
A really hacky workaround might be to not copy values that look like stringified references.