our
$VERSION
=
'0.000002'
;
$VERSION
=
eval
$VERSION
;
sub
import
{
my
$targ
=
caller
;
strict->
import
;
warnings->
import
;
no
strict
'refs'
;
@$_
or
@$_
= (
'Mu::Tiny::Object'
)
for
my
$isa
= \@{
"${targ}::ISA"
};
my
$attrs
;
*{
"${targ}::extends"
} =
sub
{
Carp::croak
"Can't call extends after attributes"
if
$attrs
;
Carp::croak
"No superclass list passed to extends"
unless
@_
;
foreach
my
$el
(
@_
) {
require
join
(
'/'
,
split
'::'
,
$el
).
'.pm'
;
}
@$isa
=
@_
;
};
*{
"${targ}::ro"
} =
sub
{
Carp::croak
"No name passed to ro"
unless
my
$name
=
shift
;
Carp::croak
"Extra args passed to ro"
if
@_
;
(
$attrs
||=_setup_attrs(
$targ
))->{
$name
} = 1;
*{
"${targ}::${name}"
} =
sub
{
$_
[0]->{
$name
} };
};
*{
"${targ}::lazy"
} =
sub
{
Carp::croak
"No name passed to lazy"
unless
my
$name
=
shift
;
Carp::croak
"No builder passed to lazy"
unless
my
$builder
=
shift
;
Carp::croak
"Extra args passed to lazy"
if
@_
;
(
$attrs
||=_setup_attrs(
$targ
))->{
$name
} = 0;
if
(
ref
(
$builder
) eq
'CODE'
) {
my
$method
=
"_build_${name}"
;
*{
"${targ}::${method}"
} =
$builder
;
$builder
=
$method
;
}
elsif
(
ref
(
$builder
)) {
Carp::croak
"Builder passed to lazy must be name or code, not ${builder}"
;
}
*{
"${targ}::${name}"
} =
sub
{
exists
(
$_
[0]->{
$name
})
?
$_
[0]->{
$name
}
: (
$_
[0]->{
$name
} =
$_
[0]->
$builder
)
};
};
}
my
$ATTRS
=
'__Mu__Tiny__attrs'
;
sub
_setup_attrs {
my
(
$targ
) =
@_
;
my
$attrs
= {};
my
$orig
=
$targ
->can(
$ATTRS
);
Carp::croak
"Can't find Mu::Tiny attrs method ${ATTRS} in ${targ}"
unless
$orig
;
no
strict
'refs'
;
*{
"${targ}::${ATTRS}"
} =
sub
{
$_
[0]->
$orig
,
%$attrs
};
$attrs
;
}
sub
__Mu__Tiny__attrs { () }
my
%spec
;
sub
new {
my
$class
=
shift
;
my
(
$attr
,
$req
) = @{
$spec
{
$class
} ||=
do
{
my
%attrs
=
$class
->__Mu__Tiny__attrs;
[[
sort
keys
%attrs
], [
sort
grep
$attrs
{
$_
},
keys
%attrs
]];
}};
my
%args
=
@_
?
@_
> 1 ?
@_
: %{
$_
[0]} : ();
my
@missing
=
grep
!
exists
(
$args
{
$_
}),
@$req
;
Carp::croak
"Missing required attributes: "
.
join
(
', '
,
@missing
)
if
@missing
;
my
%new
=
map
{
exists
(
$args
{
$_
}) ? (
$_
=>
$args
{
$_
}) : () }
@$attr
;
bless
(\
%new
,
ref
(
$class
) ||
$class
);
}
$INC
{
"Mu/Tiny/Object.pm"
} = __FILE__;
1;
=head1 NAME
Mu::Tiny - NAE KING! NAE QUIN! NAE CAPTAIN! WE WILLNAE BE FOOLED AGAIN!
=head1 SYNOPSIS
BEGIN {
ro
'name'
;
lazy
plan
=>
sub
{
'PLN'
};
}
my
$rob
= Feegle->new(
name
=>
'Rob Anybody'
);
say
$rob
->plan;
=head1 DESCRIPTION
This is the aaaabsoluuuute baaaaare minimumimumimum subset o' L<Mu>,
for
those o' ye who value yer independence over yer sanity. It doesnae trouble
wi
' anythin'
but the
read
-onlies,
for
tis a terrible thing to make a feegle
try
t'
write
.
=head1 METHODS
=head2 new
my
$new
= Feegle->new(
%attrs
|\
%attrs
);
The new method be inherited from C<Mu::Tiny::Object> like a shiny thing or
the duties o' a Kelda.
Ye may hand it a hash, or
if
ye already made yer own hash o' things, a
reference to the one so pre-prepared.
An ye forget any o' the attrs declared as L</ro>, then C<new> will go
waily waily waily and C<croak>
with
a list of all that ye missed.
=head1 EXPORTS
=head2 ro
ro
'attr'
;
An C<ro> attr be required and
read
only, and knows nothin' but its own name.
=head2 lazy
lazy
'attr'
=>
sub
{ <build
default
value> };
A C<lazy> attr be
read
only but not required, an
' if ye make us, we'
ll take a
guess at what ye wanted, but only
when
we must.
If'n ye be slightly less lazy than us, then subclass and
override
yan
C<_build_attr> method t' change tha guess.
=head1 WHUT
Dinnae fash yersel
', Hamish, you prob'
ly wanted L<Mu> anyway.
=head1 APOLOGIES
... to Terry Pratchett, Mithaldu, and probably everybody
else
as well.
=head1 AUTHOR
mst - Matt S. Trout (cpan:MSTROUT) <mst
@shadowcat
.co.uk>
=head1 CONTRIBUTORS
None yet - maybe this software is perfect! (ahahahahahahahahaha)
=head1 COPYRIGHT
Copyright (c) 2020 the Mu::Tiny L</AUTHOR> and L</CONTRIBUTORS>
as listed above.
=head1 LICENSE
This library is free software and may be distributed under the same terms
as perl itself.