Skip Menu |

This queue is for tickets about the Class-Std CPAN distribution.

Report information
The Basics
Id: 14061
Status: new
Priority: 0/
Queue: Class-Std

People
Owner: Nobody in particular
Requestors: marvin [...] rectangular.com
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 0.0.4
Fixed in: (no value)



Subject: apply :init_arg and :default before BUILD
Currently, it is not possible to know the values of ATTRS which are being set via :init_arg or :default during the BUILD phase. This makes it impossible to create derivative values within BUILD based on these ATTRS. The solution is to move the INIT loop before the BUILD loop in Class::Std, while continuing to defer the check for missing init_args until after BUILD. Test case below, patch attached. -- Marvin Humphrey #-------------------------------------------------------------------- #!/usr/bin/perl # no_deriv.plx -- demonstrate inability to derive values during BUILD package NoDeriv; use strict; use warnings; use Class::Std; my %basename_of :ATTR(:init_arg<basename> :default<'index'>); my %filename_of :ATTR; sub BUILD { my ($self, $ident, $arg_ref) = @_; # Fails because we don't know $filename_of{$ident} yet. $filename_of{$ident} = "$basename_of{$ident}.html"; } my $foo = NoDeriv->new();
--- lib/Class/Std.old 2005-08-08 10:43:57.000000000 -0700 +++ lib/Class/Std.pm 2005-08-08 10:01:46.000000000 -0700 @@ -375,11 +375,6 @@ BUILD: for my $base_class (_reverse_hierarchy_of($class)) { my %arg_set = ( %{$arg_ref}, %{$arg_ref->{$base_class}||{}} ); - # Apply BUILD() methods... - if (my $build_ref = *{$base_class.'::BUILD'}{CODE}) { - $build_ref->($new_obj, $new_obj_id, \%arg_set); - } - # Apply init_arg and default for attributes still undefined... INIT: for my $attr_ref ( @{$attribute{$base_class}} ) { @@ -403,6 +398,17 @@ next INIT; } + } + + # Apply BUILD() methods... + if (my $build_ref = *{$base_class.'::BUILD'}{CODE}) { + $build_ref->($new_obj, $new_obj_id, \%arg_set); + } + + # Detect missing required attrs... + CHECK_MISSING: + for my $attr_ref ( @{$attribute{$base_class}} ) { + next CHECK_MISSING if defined $attr_ref->{ref}{$new_obj_id}; if (defined $attr_ref->{init_arg}) { # Record missing init_arg... push @missing_inits,