BEGIN {
%^H = ();
my %clear_hints = sub { %{(caller(0))[10]||{}} }->();
$INC{'ClearHintsHash.pm'} = __FILE__;
package ClearHintsHash;
sub hints { %clear_hints }
sub import {
$^H |= 0x020000;
%^H = hints;
}
}
use strict;
use warnings;
no warnings 'once';
use Test::More;
use Test::Fatal;
use Sub::Quote qw(
quote_sub
unquote_sub
quoted_from_sub
);
{
use strict;
no strict 'subs';
local $TODO = "hints from caller not available on perl < 5.8"
if "$]" < 5.008_000;
like exception { quote_sub(q{ my $f = SomeBareword; ${"string_ref"} })->(); },
qr/strict refs/,
'hints preserved from context';
}
{
my $hints;
{
use strict;
no strict 'subs';
BEGIN { $hints = $^H }
}
like exception { quote_sub(q{ my $f = SomeBareword; ${"string_ref"} }, {}, { hints => $hints })->(); },
qr/strict refs/,
'hints used from options';
}
{
my $sub = do {
no warnings;
unquote_sub quote_sub(q{ 0 + undef });
};
my @warnings;
local $SIG{__WARN__} = sub { push @warnings, @_ };
$sub->();
is scalar @warnings, 0,
'"no warnings" preserved from context';
}
{
my $sub = do {
no warnings;
use warnings;
unquote_sub quote_sub(q{ 0 + undef });
};
my @warnings;
local $SIG{__WARN__} = sub { push @warnings, @_ };
$sub->();
like $warnings[0],
qr/uninitialized/,
'"use warnings" preserved from context';
}
{
my $warn_bits;
eval q{
use warnings FATAL => 'uninitialized';
BEGIN { $warn_bits = ${^WARNING_BITS} }
1;
} or die $@;
no warnings 'uninitialized';
like exception { quote_sub(q{ 0 + undef }, {}, { warning_bits => $warn_bits })->(); },
qr/uninitialized/,
'warnings used from options';
}
BEGIN {
package UseHintHash;
$INC{'UseHintHash.pm'} = 1;
sub import {
$^H |= 0x020000;
$^H{__PACKAGE__.'/enabled'} = 1;
}
}
{
my %hints;
{
use ClearHintsHash;
use UseHintHash;
BEGIN { %hints = %^H }
}
{
local $TODO = 'hints hash from context not available on perl 5.8'
if "$]" < 5.010_000;
use ClearHintsHash;
use UseHintHash;
is_deeply quote_sub(q{
our %temp_hints_hash;
BEGIN { %temp_hints_hash = %^H }
\%temp_hints_hash;
})->(), \%hints,
'hints hash preserved from context';
}
is_deeply quote_sub(q{
our %temp_hints_hash;
BEGIN { %temp_hints_hash = %^H }
\%temp_hints_hash;
}, {}, { hintshash => \%hints })->(), \%hints,
'hints hash used from options';
}
{
use ClearHintsHash;
my $sub = quote_sub(q{
our %temp_hints_hash;
BEGIN { %temp_hints_hash = %^H }
\%temp_hints_hash;
});
my $wrap_sub = do {
use UseHintHash;
my (undef, $code, $cap) = @{quoted_from_sub($sub)};
quote_sub $code, $cap||();
};
is_deeply $wrap_sub->(), { ClearHintsHash::hints },
'empty hints maintained when inlined';
}
BEGIN {
package BetterNumbers;
$INC{'BetterNumbers.pm'} = 1;
use overload ();
sub import {
my ($class, $add) = @_;
# closure vs not
if (defined $add) {
overload::constant 'integer', sub { $_[0] + $add };
}
else {
overload::constant 'integer', sub { $_[0] + 1 };
}
}
}
TODO: {
my ($options, $context_sub, $direct_val);
{
use BetterNumbers;
BEGIN { $options = { hints => $^H, hintshash => { %^H } } }
$direct_val = 10;
$context_sub = quote_sub(q{ 10 });
}
my $options_sub = quote_sub(q{ 10 }, {}, $options);
is $direct_val, 11,
'integer overload is working';
todo_skip "refs in hints hash not yet implemented", 4;
{
my $context_val;
is exception { $context_val = $context_sub->() }, undef,
'hints hash refs from context not broken';
local $TODO = 'hints hash from context not available on perl 5.8'
if !$TODO && "$]" < 5.010_000;
is $context_val, 11,
'hints hash refs preserved from context';
}
{
my $options_val;
is exception { $options_val = $options_sub->() }, undef,
'hints hash refs from options not broken';
is $options_val, 11,
'hints hash refs used from options';
}
}
TODO: {
my ($options, $context_sub, $direct_val);
{
use BetterNumbers +2;
BEGIN { $options = { hints => $^H, hintshash => { %^H } } }
$direct_val = 10;
$context_sub = quote_sub(q{ 10 });
}
my $options_sub = quote_sub(q{ 10 }, {}, $options);
is $direct_val, 12,
'closure integer overload is working';
todo_skip "refs in hints hash not yet implemented", 4;
{
my $context_val;
is exception { $context_val = $context_sub->() }, undef,
'hints hash closure refs from context not broken';
local $TODO = 'hints hash from context not available on perl 5.8'
if !$TODO && "$]" < 5.010_000;
is $context_val, 12,
'hints hash closure refs preserved from context';
}
{
my $options_val;
is exception { $options_val = $options_sub->() }, undef,
'hints hash closure refs from options not broken';
is $options_val, 12,
'hints hash closure refs used from options';
}
}
done_testing;