From e0b21df6d7872b520dd4694c07608f99813ba9bd Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 7 May 2010 04:55:31 -0500 Subject: initial implementation --- lib/MooseX/Attribute/Shorthand.pm | 55 ++++++++++++++++++++++++++++++++++++--- t/001-basic.t | 24 +++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 t/001-basic.t diff --git a/lib/MooseX/Attribute/Shorthand.pm b/lib/MooseX/Attribute/Shorthand.pm index 185f581..e8a10bf 100644 --- a/lib/MooseX/Attribute/Shorthand.pm +++ b/lib/MooseX/Attribute/Shorthand.pm @@ -1,5 +1,8 @@ package MooseX::Attribute::Shorthand; -use Moose; +use strict; +use warnings; + +use Scalar::Util qw(reftype); =head1 NAME @@ -13,8 +16,54 @@ MooseX::Attribute::Shorthand - =cut -__PACKAGE__->meta->make_immutable; -no Moose; +sub import { + my $package = shift; + my $caller = caller; + my %custom_options = @_; + my $role = Moose::Meta::Role->create_anon_role(cache => 1); + for my $option (keys %custom_options) { + my $meta_options = delete $custom_options{$option}{'-meta_attr_options'}; + $role->add_attribute($option => ( + is => 'ro', + isa => 'Bool', + %{ $meta_options || {} }, + )); + } + $role->add_around_method_modifier(_process_options => sub { + my $orig = shift; + my $class = shift; + my ($name, $options) = @_; + my %new_options; + for my $option (keys %$options) { + if (exists($custom_options{$option})) { + for my $expanded_option (keys %{ $custom_options{$option} }) { + my $expanded_val = $custom_options{$option}->{$expanded_option}; + if (reftype($expanded_val) + && reftype($expanded_val) eq 'CODE') { + $new_options{$expanded_option} = $expanded_val->( + $name, $options->{$option}, + ); + } + else { + $new_options{$expanded_option} = $expanded_val; + } + } + } + else { + $new_options{$option} = $options->{$option}; + } + } + # relies on being modified in-place + %$options = %new_options; + $class->$orig($name, $options); + }); + Moose::Util::MetaRole::apply_metaroles( + for => $caller, + class_metaroles => { + attribute => [$role->name], + }, + ); +} =head1 BUGS diff --git a/t/001-basic.t b/t/001-basic.t new file mode 100644 index 0000000..f3445a4 --- /dev/null +++ b/t/001-basic.t @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; +use Test::Exception; + +{ + package Foo; + use Moose; + use MooseX::Attribute::Shorthand string => { + is => 'ro', + isa => 'Str', + default => sub { $_[1] }, + -meta_attr_options => { isa => 'Str' }, + }; + + has foo => (string => 'FOO'); +} + +my $foo = Foo->new; +is($foo->foo, 'FOO', "expanded properly"); +dies_ok { $foo->foo('sldkfj') } "expanded properly"; + +done_testing; -- cgit v1.2.3