diff --git a/t/class/accessor.t b/t/class/accessor.t index 832637cf8996..0c05a63d3ee0 100644 --- a/t/class/accessor.t +++ b/t/class/accessor.t @@ -19,7 +19,10 @@ no warnings 'experimental::class'; field @a :reader = qw( the array ); # Present-but-empty parens counts as default + field %h :reader() = qw( the hash ); + + field $empty :reader; } my $o = Testcase1->new; @@ -35,12 +38,26 @@ no warnings 'experimental::class'; 'Reader accessor fails with argument'); like($@, qr/^Too many arguments for subroutine \'Testcase1::s\' \(got 2; expected 1\) at /, 'Failure from argument to accessor'); + + # Reading an undefined value has predictable behaviour + $o->empty; + pass("void :reader on an uninitialized field doesn't crash"); + ok(!defined scalar $o->empty, 'scalar :reader on uninitialized field is undef'); + my ($empty) = $o->empty; + ok(!defined $empty, 'list :reader on uninitialized field is undef'); + + # :reader returns value copies, not the internal SVs + map { $_ = 99 } $o->s, $o->a, $o->h; + is($o->s, "the scalar", ':reader does not expose internal SVs'); + ok(eq_array([$o->a], [qw( the array )]), ':reader does not expose internal AVs'); + ok(eq_hash({$o->h}, {qw( the hash )}), ':reader does not expose internal HVs'); } # writer accessors on scalars { class Testcase2 { field $s :reader :writer = "initial"; + field $xno :param :reader = "Eh-ehhh"; } my $o = Testcase2->new; @@ -57,6 +74,12 @@ no warnings 'experimental::class'; 'Writer accessor fails with 2 arguments'); like($@, qr/^Too many arguments for subroutine \'Testcase2::set_s\' \(got 3; expected 2\) at /, 'Failure from argument to accessor'); + + # Should not be able to write without the :writer attribute + ok(!eval { $o->set_xno(77) }, + 'Cannot write without :writer attribute'); + like($@, qr/^Can\'t locate object method \"set_xno\" via package \"Testcase2\"/, + 'Failure from writing without :writer'); } # Alternative names @@ -76,4 +99,6 @@ no warnings 'experimental::class'; 'Failure from lack of original name accessor'); } +# Note: see t/lib/croak/class for testing :writer accessors on AVs or HVs + done_testing; diff --git a/t/lib/croak/class b/t/lib/croak/class index 5ce19411190e..a0ad0184dbbd 100644 --- a/t/lib/croak/class +++ b/t/lib/croak/class @@ -175,7 +175,7 @@ class XXX { EXPECT "set-abc-def" is not a valid name for a generated method at - line 6. ######## -# Writer on non-scalar field +# Writer on array field use v5.36; use feature 'class'; no warnings 'experimental::class'; @@ -185,6 +185,16 @@ class XXX { EXPECT Cannot apply a :writer attribute to a non-scalar field at - line 6. ######## +# Writer on hash field +use v5.36; +use feature 'class'; +no warnings 'experimental::class'; +class XXX { + field %things :writer; +} +EXPECT +Cannot apply a :writer attribute to a non-scalar field at - line 6. +######## use v5.36; use feature 'class'; no warnings 'experimental::class';