From: gfx Date: Tue, 22 Dec 2009 06:59:03 +0000 (+0900) Subject: Effort to the strict constructor X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6fd8aa82f783628e6dfb8accf73d93ebd59ece85;p=gitmo%2FMouse.git Effort to the strict constructor --- diff --git a/lib/Mouse/Meta/Attribute.pm b/lib/Mouse/Meta/Attribute.pm index 3df565a..c9cc8dc 100644 --- a/lib/Mouse/Meta/Attribute.pm +++ b/lib/Mouse/Meta/Attribute.pm @@ -5,6 +5,21 @@ use Carp (); use Mouse::Meta::TypeConstraint; +#my @attributes = qw( +# name init_arg required +# is +# isa does coerce +# accessor reader writer predicate clearer +# default builder lazy lazy_build +# auto_deref trigger +# metaclass traits +# +# handles +# documentation +# +# type_constraint +#); + sub _process_options{ my($class, $name, $args) = @_; diff --git a/xs-src/Mouse.xs b/xs-src/Mouse.xs index b3d411c..74ef113 100644 --- a/xs-src/Mouse.xs +++ b/xs-src/Mouse.xs @@ -238,11 +238,38 @@ mouse_buildargs(pTHX_ SV* metaclass, SV* const klass, I32 ax, I32 items) { } static void +mouse_report_unmatched_keys(pTHX_ SV* const meta, AV* const attrs, HV* const args) { + HV* const attr_map = newHV_mortal(); + I32 const len = AvFILLp(attrs) + 1; + I32 i; + SV* const unknown = newSVpvs_flags("", SVs_TEMP); + HE* he; + + for(i = 0; i < len; i++){ + SV* const attr = MOUSE_av_at(attrs, i); + (void)hv_store_ent(attr_map, mcall0(attr, mouse_name), &PL_sv_yes, 0U); + } + + hv_iterinit(args); + while((he = hv_iternext(args))){ + SV* const key = hv_iterkeysv(he); + if(!hv_exists_ent(attr_map, key, 0U)){ + sv_catpvf(unknown, " %"SVf",", key); + } + } + SvCUR(unknown)--; /* chop "," */ + mouse_throw_error(meta, NULL, + "Unknown attribute init_arg passed to the constructor of %"SVf": %"SVf, + mcall0(meta, mouse_name), unknown); +} + +static void mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const args, bool const ignore_triggers) { AV* const xc = mouse_get_xc(aTHX_ meta); AV* const attrs = MOUSE_xc_attrall(xc); I32 len = AvFILLp(attrs) + 1; I32 i; + I32 used = 0; AV* triggers_queue = NULL; assert(meta || object); @@ -281,6 +308,8 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const av_push(triggers_queue, (SV*)pair); } + + used++; } else { /* no init arg */ if(flags & (MOUSEf_ATTR_HAS_DEFAULT | MOUSEf_ATTR_HAS_BUILDER)){ @@ -305,6 +334,10 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const } } + if(used < HvUSEDKEYS(args)){ + mouse_report_unmatched_keys(aTHX_ meta, attrs, args); + } + if(MOUSE_xc_flags(xc) & MOUSEf_XC_IS_ANON){ set_slot(object, newSVpvs_flags("__METACLASS__", SVs_TEMP), meta); }