--- /dev/null
+package Method::Generate::Accessor;
+
+use strictures 1;
+use Class::Tiny::_Utils;
+use base qw(Class::Tiny::Object);
+use Sub::Quote;
+use B 'perlstring';
+
+sub generate_methods {
+ my ($self, $into, $name, $spec) = @_;
+ die "Must have an is" unless my $is = $spec->{is};
+ my $name_str = perlstring $name;
+ my $body = do {
+ if ($is eq 'ro') {
+ ' '.$self->_generate_get($name_str)
+ } elsif ($is eq 'rw') {
+ ' '.$self->_generate_getset($name_str)
+ } else {
+ die "Unknown is ${is}";
+ }
+ };
+ quote_sub "${into}::${name}" => $body;
+}
+
+sub _generate_get {
+ my ($self, $name_str) = @_;
+ "\$_[0]->{${name_str}}";
+}
+
+sub _generate_set {
+ my ($self, $name_str, $value) = @_;
+ "\$_[0]->{${name_str}} = ${value}";
+}
+
+sub _generate_getset {
+ my ($self, $name_str) = @_;
+ q{(@_ > 1 ? }.$self->_generate_set($name_str, q{$_[1]})
+ .' : '.$self->_generate_get($name_str).')';
+}
+
+1;
--- /dev/null
+use strictures 1;
+use Test::More;
+use Test::Fatal;
+
+use Method::Generate::Accessor;
+
+my $gen = Method::Generate::Accessor->new;
+
+{
+ package Foo;
+ use Class::Tiny;
+}
+
+$gen->generate_methods('Foo' => 'one' => { is => 'ro' });
+
+$gen->generate_methods('Foo' => 'two' => { is => 'rw' });
+
+like(
+ exception { $gen->generate_methods('Foo' => 'three' => {}) },
+ qr/Must have an is/, 'No is rejected'
+);
+
+like(
+ exception { $gen->generate_methods('Foo' => 'three' => { is => 'purple' }) },
+ qr/Unknown is purple/, 'is purple rejected'
+);
+
+my $foo = Foo->new(one => 1);
+
+is($foo->one, 1, 'ro reads');
+$foo->one(-3);
+is($foo->one, 1, 'ro does not write');
+
+is($foo->two, undef, 'rw reads');
+$foo->two(-3);
+is($foo->two, -3, 'rw writes');
+
+done_testing;