MooseX::Blessed::Reconstruct - A L<Data::Visitor> for creating Moose objects


MooseX-Blessed-Reconstruct documentation Contained in the MooseX-Blessed-Reconstruct distribution.

Index


Code Index:

NAME

Top

MooseX::Blessed::Reconstruct - A Data::Visitor for creating Moose objects from blessed placeholders

SYNOPSIS

Top

	use MooseX::Blessed::Reconstruct;




	my $obj = bless( {
		init_arg_foo => "Blah",
		arf => "yay",
	}, "Foo" );

	my $proper = MooseX::Blessed::Reconstruct->new->visit($obj);







	# equivalent to:

	my $proper = Foo->meta->new_object(%$obj);

	# but recursive (and works with shared references)

DESCRIPTION

Top

The purpose of this module is to "fix up" blessed data into a real Moose object.

This is used internally by MooseX::YAML but has no implementation details having to do with YAML itself.

METHODS

Top

See Data::Visitor

visit_object $object

Calls load_class in Class::MOP on the ref of $object.

If there's a metaclass, calls visit_object_with_meta, otherwise visit_ref is used to walk the object brutishly.

Returns a deep clone of the input structure with all the Moose objects reconstructed "properly".

visit_object_with_meta $obj, $meta

Uses the metaclass $meta to create a new instance, registers the instance with Data::Visitor's cycle tracking, and then inflates it using new_object in Moose::Meta::Class.

prepare_args $obj

Collapses $obj into key value pairs to be used as init args to new_object in Moose::Meta::Class.

VERSION CONTROL

Top

This module is maintained using Darcs. You can get the latest version from http://nothingmuch.woobling.org/code, and use darcs send to commit changes.

AUTHOR

Top

Jonathan Rockway

Yuval Kogman <nothingmuch@woobling.org>

COPYRIGHT

Top


MooseX-Blessed-Reconstruct documentation Contained in the MooseX-Blessed-Reconstruct distribution.

#!/usr/bin/perl

package MooseX::Blessed::Reconstruct;
use Moose;

use Carp qw(croak);

use Class::MOP 0.66; # well behaved load_class()
use Data::Visitor 0.21; # n-arity visit

use Scalar::Util qw(reftype);

use namespace::clean -except => 'meta';

our $VERSION = "0.04";

extends qw(Data::Visitor);

has load_classes => (
	isa => "Bool",
	is  => "rw",
	default => 1,
);

sub visit_object {
	my ( $v, $obj ) = @_;

	my $class = ref $obj;

	Class::MOP::load_class($class) if $v->load_classes;

	my $meta = Class::MOP::get_metaclass_by_name($class);

	if ( ref $meta ) {
		return $v->visit_object_with_meta($obj, $meta);
	} else {
		return $v->visit_ref($obj);
	}
}

sub visit_object_with_meta {
	my ( $v, $obj, $meta ) = @_;

	my $instance = $meta->get_meta_instance->create_instance;

	$v->_register_mapping( $obj => $instance );

	my $args = $v->prepare_args( $meta, $obj );

	$meta->new_object( %$args, __INSTANCE__ => $instance );

	return $instance;
}

sub prepare_args {
	my ( $v, $meta, $obj ) = @_;

    my @args;

    if ( reftype $obj eq 'HASH' ) {
        @args = %$obj;
    } elsif ( reftype $obj eq 'ARRAY' ) {
        @args = @$obj;
    } elsif ( reftype $obj eq 'SCALAR' ) {
        @args = $$obj;
    } else {
        croak "unknown ref type $obj";
    }

    my @processed = $v->visit(@args);

    return $meta->name->BUILDARGS(@processed);
}

__PACKAGE__->meta->make_immutable;

__PACKAGE__

__END__