- attribute slot initialization is now the responsibility
of the attribute itself, so we added a method for it
called initialize_instance_slot
+
+ * examples/
+ - adjusted all the examples to use the new attribute
+ initialize_instance_slot method
0.24 Tues. April 11, 2006
* Class::MOP::Class
use strict;
use warnings;
-our $VERSION = '0.04';
+our $VERSION = '0.05';
use base 'Class::MOP::Class';
my $meta = $current_class->meta;
foreach my $attr_name ($meta->get_attribute_list()) {
my $attr = $meta->get_attribute($attr_name);
- # if the attr has an init_arg, use that, otherwise,
- # use the attributes name itself as the init_arg
- my $init_arg = $attr->init_arg();
- # try to fetch the init arg from the %params ...
- my $val;
- $val = $params{$current_class}->{$init_arg}
- if exists $params{$current_class} &&
- exists ${$params{$current_class}}{$init_arg};
- # if nothing was in the %params, we can use the
- # attribute's default value (if it has one)
- if (!defined $val && $attr->has_default) {
- $val = $attr->default($instance);
- }
- # now add this to the instance structure
- $instance->{$current_class}->{$attr_name} = $val;
+ $attr->initialize_instance_slot($meta, $instance, \%params);
}
}
return $instance;
use strict;
use warnings;
-our $VERSION = '0.02';
+our $VERSION = '0.03';
use base 'Class::MOP::Attribute';
+sub initialize_instance_slot {
+ my ($self, $class, $instance, $params) = @_;
+ # if the attr has an init_arg, use that, otherwise,
+ # use the attributes name itself as the init_arg
+ my $init_arg = $self->init_arg();
+ # try to fetch the init arg from the %params ...
+ my $val;
+ $val = $params->{$class->name}->{$init_arg}
+ if exists $params->{$class->name} &&
+ exists ${$params->{$class->name}}{$init_arg};
+ # if nothing was in the %params, we can use the
+ # attribute's default value (if it has one)
+ if (!defined $val && $self->has_default) {
+ $val = $self->default($instance);
+ }
+ # now add this to the instance structure
+ $instance->{$class->name}->{$self->name} = $val;
+}
+
sub generate_accessor_method {
my ($self, $attr_name) = @_;
my $class_name = $self->associated_class->name;
-package # hide the package from PAUSE
- InsideOutClass;
-
-use strict;
-use warnings;
-
-our $VERSION = '0.04';
-
-use Scalar::Util 'refaddr';
-
-use base 'Class::MOP::Class';
-
-sub construct_instance {
- my ($class, %params) = @_;
- # create a scalar ref to use as
- # the inside-out instance
- my $instance = \(my $var);
- foreach my $attr ($class->compute_all_applicable_attributes()) {
- # if the attr has an init_arg, use that, otherwise,
- # use the attributes name itself as the init_arg
- my $init_arg = $attr->init_arg();
- # try to fetch the init arg from the %params ...
- my $val;
- $val = $params{$init_arg} if exists $params{$init_arg};
- # if nothing was in the %params, we can use the
- # attribute's default value (if it has one)
- if (!defined $val && $attr->has_default) {
- $val = $attr->default($instance);
- }
- # now add this to the instance structure
- $class->get_package_variable('%' . $attr->name)->{ refaddr($instance) } = $val;
- }
- return $instance;
-}
package # hide the package from PAUSE
InsideOutClass::Attribute;
use strict;
use warnings;
-our $VERSION = '0.04';
+our $VERSION = '0.05';
use Carp 'confess';
use Scalar::Util 'refaddr';
use base 'Class::MOP::Attribute';
+sub initialize_instance_slot {
+ my ($self, $class, $instance, $params) = @_;
+ # if the attr has an init_arg, use that, otherwise,
+ # use the attributes name itself as the init_arg
+ my $init_arg = $self->init_arg();
+ # try to fetch the init arg from the %params ...
+ my $val;
+ $val = $params->{$init_arg} if exists $params->{$init_arg};
+ # if nothing was in the %params, we can use the
+ # attribute's default value (if it has one)
+ if (!defined $val && $self->has_default) {
+ $val = $self->default($instance);
+ }
+ # now add this to the instance structure
+ $class->get_package_variable('%' . $self->name)->{ refaddr($instance) } = $val;
+}
+
sub generate_accessor_method {
my ($self, $attr_name) = @_;
$attr_name = ($self->associated_class->name . '::' . $attr_name);
package Foo;
- use metaclass 'InsideOutClass' => (
+ use metaclass 'Class::MOP::Class' => (
# tell our metaclass to use the
# InsideOut attribute metclass
# to construct all it's attributes
class technique. What follows is a brief explaination of the code
found in this module.
-First step is to subclass B<Class::MOP::Class> and override the
-C<construct_instance> method. The default C<construct_instance>
-will create a HASH reference using the parameters and attribute
-default values. Since inside-out objects don't use HASH refs, and
-use package variables instead, we need to write code to handle
-this difference.
-
-The next step is to create the subclass of B<Class::MOP::Attribute>
-and override the method generation code. This requires overloading
-C<generate_accessor_method>, C<generate_reader_method>,
-C<generate_writer_method> and C<generate_predicate_method>. All
-other aspects are taken care of with the existing B<Class::MOP::Attribute>
-infastructure.
+We must create a subclass of B<Class::MOP::Attribute> and override
+the instance initialization and method generation code. This requires
+overloading C<initialize_instance_slot>, C<generate_accessor_method>,
+C<generate_reader_method>, C<generate_writer_method> and
+C<generate_predicate_method>. All other aspects are taken care of with
+the existing B<Class::MOP::Attribute> infastructure.
And that is pretty much all. Of course I am ignoring need for
inside-out objects to be C<DESTROY>-ed, and some other details as
package # hide the package from PAUSE
- LazyClass;
-
-use strict;
-use warnings;
-
-our $VERSION = '0.02';
-
-use base 'Class::MOP::Class';
-
-sub construct_instance {
- my ($class, %params) = @_;
- my $instance = {};
- foreach my $attr ($class->compute_all_applicable_attributes()) {
- # if the attr has an init_arg, use that, otherwise,
- # use the attributes name itself as the init_arg
- my $init_arg = $attr->init_arg();
- # try to fetch the init arg from the %params ...
- my $val;
- $val = $params{$init_arg} if exists $params{$init_arg};
- # now add this to the instance structure
- # only if we have found a value at all
- $instance->{$attr->name} = $val if defined $val;
- }
- return $instance;
-}
-
-package # hide the package from PAUSE
LazyClass::Attribute;
use strict;
use Carp 'confess';
-our $VERSION = '0.02';
+our $VERSION = '0.03';
use base 'Class::MOP::Attribute';
+sub initialize_instance_slot {
+ my ($self, $class, $instance, $params) = @_;
+ # if the attr has an init_arg, use that, otherwise,
+ # use the attributes name itself as the init_arg
+ my $init_arg = $self->init_arg();
+ # try to fetch the init arg from the %params ...
+ my $val;
+ $val = $params->{$init_arg} if exists $params->{$init_arg};
+ # now add this to the instance structure
+ # only if we have found a value at all
+ $instance->{$self->name} = $val if defined $val;
+}
+
+
sub generate_accessor_method {
my ($self, $attr_name) = @_;
sub {
package BinaryTree;
- use metaclass 'LazyClass' => (
+ use metaclass 'Class::MOP::Class' => (
':attribute_metaclass' => 'LazyClass::Attribute'
);
}
sub initialize_instance_slot {
- my ($self, $instance, $params) = @_;
+ my ($self, $class, $instance, $params) = @_;
my $init_arg = $self->init_arg();
# try to fetch the init arg from the %params ...
my $val;
my ($class, %params) = @_;
my $instance = {};
foreach my $attr ($class->compute_all_applicable_attributes()) {
- $attr->initialize_instance_slot($instance, \%params);
+ $attr->initialize_instance_slot($class, $instance, \%params);
}
return $instance;
}
{
package Foo;
- use metaclass 'InsideOutClass' => (
+ use metaclass 'Class::MOP::Class' => (
':attribute_metaclass' => 'InsideOutClass::Attribute'
);
{
package BinaryTree;
- use metaclass 'LazyClass' => (
+ use metaclass 'Class::MOP::Class' => (
':attribute_metaclass' => 'LazyClass::Attribute'
);