package main;
$| = 1;
-use Test::More tests => 556;
+use Test::More tests => 607;
$a = new Oscalar "087";
}
is($int, 9);
is($out, 1024);
+is($int, 9);
+{
+ BEGIN { overload::constant 'integer' => sub {$int++; shift()+1}; }
+ eval q{$out = 42};
+}
+is($int, 10);
+is($out, 43);
$foo = 'foo';
$foo1 = 'f\'o\\o';
}
{
+ {
+ package QRonly;
+ use overload qr => sub { qr/x/ }, fallback => 1;
+ }
+ {
+ my $x = bless [], "QRonly";
+
+ # like tries to be too clever, and decides that $x-stringified
+ # doesn't look like a regex
+ ok("x" =~ $x, "qr-only matches");
+ ok("y" !~ $x, "qr-only doesn't match what it shouldn't");
+ ok("xx" =~ /x$x/, "qr-only matches with concat");
+ like("$x", qr/^QRonly=ARRAY/, "qr-only doesn't have string overload");
+
+ my $qr = bless qr/y/, "QRonly";
+ ok("x" =~ $qr, "qr with qr-overload uses overload");
+ ok("y" !~ $qr, "qr with qr-overload uses overload");
+ is("$qr", "".qr/y/, "qr with qr-overload stringify");
+
+ my $rx = $$qr;
+ ok("y" =~ $rx, "bare rx with qr-overload doesn't overload match");
+ ok("x" !~ $rx, "bare rx with qr-overload doesn't overload match");
+ is("$rx", "".qr/y/, "bare rx with qr-overload stringify");
+ }
+ {
+ package QRandSTR;
+ use overload qr => sub { qr/x/ }, q/""/ => sub { "y" };
+ }
+ {
+ my $x = bless [], "QRandSTR";
+ ok("x" =~ $x, "qr+str uses qr for match");
+ ok("y" !~ $x, "qr+str uses qr for match");
+ ok("xx" =~ /x$x/, "qr+str uses qr for match with concat");
+ is("$x", "y", "qr+str uses str for stringify");
+
+ my $qr = bless qr/z/, "QRandSTR";
+ is("$qr", "y", "qr with qr+str uses str for stringify");
+ ok("xx" =~ /x$x/, "qr with qr+str uses qr for match");
+
+ my $rx = $$qr;
+ ok("z" =~ $rx, "bare rx with qr+str doesn't overload match");
+ is("$rx", "".qr/z/, "bare rx with qr+str doesn't overload stringify");
+ }
+ {
+ package QRany;
+ use overload qr => sub { $_[0]->(@_) };
+
+ package QRself;
+ use overload qr => sub { $_[0] };
+ }
+ {
+ my $rx = bless sub { ${ qr/x/ } }, "QRany";
+ ok("x" =~ $rx, "qr overload accepts a bare rx");
+ ok("y" !~ $rx, "qr overload accepts a bare rx");
+
+ my $str = bless sub { "x" }, "QRany";
+ ok(!eval { "x" =~ $str }, "qr overload doesn't accept a string");
+ like($@, qr/^Overloaded qr did not return a REGEXP/, "correct error");
+
+ my $oqr = bless qr/z/, "QRandSTR";
+ my $oqro = bless sub { $oqr }, "QRany";
+ ok("z" =~ $oqro, "qr overload doesn't recurse");
+
+ my $qrs = bless qr/z/, "QRself";
+ ok("z" =~ $qrs, "qr overload can return self");
+ }
+ {
+ package STRonly;
+ use overload q/""/ => sub { "x" };
+
+ package STRonlyFB;
+ use overload q/""/ => sub { "x" }, fallback => 1;
+ }
+ {
+ my $fb = bless [], "STRonlyFB";
+ ok("x" =~ $fb, "qr falls back to \"\"");
+ ok("y" !~ $fb, "qr falls back to \"\"");
+
+ my $nofb = bless [], "STRonly";
+ ok("x" =~ $nofb, "qr falls back even without fallback");
+ ok("y" !~ $nofb, "qr falls back even without fallback");
+ }
+}
+
+{
my $twenty_three = 23;
# Check that constant overloading propagates into evals
BEGIN { overload::constant integer => sub { 23 } }
ok(!$b, "Expect overloaded boolean");
ok(!$a, "Expect overloaded boolean");
}
+
+{
+ package Flrbbbbb;
+ use overload
+ bool => sub { shift->{truth} eq 'yes' },
+ '0+' => sub { shift->{truth} eq 'yes' ? '1' : '0' },
+ '!' => sub { shift->{truth} eq 'no' },
+ fallback => 1;
+
+ sub new { my $class = shift; bless { truth => shift }, $class }
+
+ package main;
+
+ my $yes = Flrbbbbb->new('yes');
+ my $x;
+ $x = 1 if $yes; is($x, 1);
+ $x = 2 unless $yes; is($x, 1);
+ $x = 3 if !$yes; is($x, 1);
+ $x = 4 unless !$yes; is($x, 4);
+
+ my $no = Flrbbbbb->new('no');
+ $x = 0;
+ $x = 1 if $no; is($x, 0);
+ $x = 2 unless $no; is($x, 2);
+ $x = 3 if !$no; is($x, 3);
+ $x = 4 unless !$no; is($x, 3);
+
+ $x = 0;
+ $x = 1 if !$no && $yes; is($x, 1);
+ $x = 2 unless !$no && $yes; is($x, 1);
+ $x = 3 if $no || !$yes; is($x, 1);
+ $x = 4 unless $no || !$yes; is($x, 4);
+
+ $x = 0;
+ $x = 1 if !$no || !$yes; is($x, 1);
+ $x = 2 unless !$no || !$yes; is($x, 1);
+ $x = 3 if !$no && !$yes; is($x, 1);
+ $x = 4 unless !$no && !$yes; is($x, 4);
+}
+
{
use Scalar::Util 'weaken';
}
{
- # comparison operators with nomethod
+ # comparison operators with nomethod (bug 41546)
my $warning = "";
my $method;
}
{
+ # nomethod called for '!' after attempted fallback
+ my $nomethod_called = 0;
+
+ package nomethod_not;
+ use overload nomethod => sub { $nomethod_called = 'yes'; };
+
+ package main;
+ my $o = bless [], 'nomethod_not';
+ my $res = ! $o;
+
+ is($nomethod_called, 'yes', "nomethod() is called for '!'");
+ is($res, 'yes', "nomethod(..., '!') return value propagates");
+}
+
+{
# Subtle bug pre 5.10, as a side effect of the overloading flag being
# stored on the reference rather than the referent. Despite the fact that
# objects can only be accessed via references (even internally), the
is($m+$m, 2*$num_val, 'numifies to usual reference value');
is(0-$m, -$num_val, 'numifies to usual reference value');
is(1*$m, $num_val, 'numifies to usual reference value');
- is($m/1, $num_val, 'numifies to usual reference value');
+ is(int($m/1), $num_val, 'numifies to usual reference value');
is($m%100, $num_val%100, 'numifies to usual reference value');
is($m**1, $num_val, 'numifies to usual reference value');
is($aref+$aref, 2*$num_val, 'ref addition');
is(0-$aref, -$num_val, 'subtraction of ref');
is(1*$aref, $num_val, 'multiplicaton of ref');
- is($aref/1, $num_val, 'division of ref');
+ is(int($aref/1), $num_val, 'division of ref');
is($aref%100, $num_val%100, 'modulo of ref');
is($aref**1, $num_val, 'exponentiation of ref');
}
+{
+ package CopyConstructorFallback;
+ use overload
+ '++' => sub { "$_[0]"; $_[0] },
+ fallback => 1;
+ sub new { bless {} => shift }
+
+ package main;
+
+ my $o = CopyConstructorFallback->new;
+ my $x = $o++; # would segfault
+ my $y = ++$o;
+ is($x, $o, "copy constructor falls back to assignment (postinc)");
+ is($y, $o, "copy constructor falls back to assignment (preinc)");
+}
+
# EOF