Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
       Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass -	A method
       metaclass for marking methods public or private

       version 2.2005

	 package MyApp::Meta::Method::PrivateOrPublic;

	 use Moose;
	 use Moose::Util::TypeConstraints;

	 extends 'Moose::Meta::Method';

	 has '_policy' => (
	     is	      => 'ro',
	     isa      => enum( [ qw( public private ) ]	),
	     default  => 'public',
	     init_arg => 'policy',

	 sub new {
	     my	$class	 = shift;
	     my	%options = @_;

	     my	$self =	$class->SUPER::wrap(%options);

	     $self->{_policy} =	$options{policy};


	     return $self;

	 sub _add_policy_wrapper {
	     my	$self =	shift;

	     return if $self->is_public;

	     my	$name	   = $self->name;
	     my	$package   = $self->package_name;
	     my	$real_body = $self->body;

	     my	$body =	sub {
		 die "The $package\::$name method is private"
		     unless ( scalar caller() )	eq $package;

		 goto &{$real_body};

	     $self->{body} = $body;

	 sub is_public	{ $_[0]->_policy eq 'public' }
	 sub is_private	{ $_[0]->_policy eq 'private' }

	 package MyApp::User;

	 use Moose;

	 has 'password'	=> ( is	=> 'rw'	);

		 name	      => '_reset_password',
		 package_name => __PACKAGE__,
		 body	      => sub { $_[0]->password('reset')	},
		 policy	      => 'private',

       This example shows a custom method metaclass that models	public versus
       private methods.	If a method is defined as private, it adds a wrapper
       around the method which dies unless it is called	from the class where
       it was defined.

       The way the method is added to the class	is rather ugly.	If we wanted
       to make this a real feature, we'd probably want to add some sort	of
       sugar to	allow us to declare private methods, but that is beyond	the
       scope of	this recipe. See the Extending recipes for more	on this	topic.

       The core	of our custom class is the "policy" attribute, and
       "_add_policy_wrapper" method.

       You'll note that	we have	to explicitly set the "policy" attribute in
       our constructor:

	     $self->{_policy} =	$options{policy};

       That is necessary because Moose metaclasses do not use the meta API to
       create objects. Most Moose classes have a custom	"inlined" constructor
       for speed.

       In this particular case,	our parent class's constructor is the "wrap"
       method. We call that to build our object, but it	does not include
       subclass-specific attributes.

       The "_add_policy_wrapper" method	is where the real work is done.	If the
       method is private, we construct a wrapper around	the real subroutine
       which checks that the caller matches the	package	in which the
       subroutine was created.

       If they don't match, it dies. If	they do	match, the real	method is
       called. We use "goto" so	that the wrapper does not show up in the call

       Finally,	we replace the value of	"$self->{body}". This is another case
       where we	have to	do something a bit gross because Moose does not	use
       Moose for its own implementation.

       When we pass this method	object to the metaclass's "add_method" method,
       it will take the	method body and	make it	available in the class.

       Finally,	when we	retrieve these methods via the introspection API, we
       can call	the "is_public"	and "is_private" methods on them to get	more
       information about the method.

       A custom	method metaclass lets us add both behavior and meta-
       information to methods. Unfortunately, because the Perl interpreter
       does not	provide	easy hooks into	method declaration, the	API we have
       for adding these	methods	is not very pretty.

       That can	be improved with custom	Moose-like sugar, or even by using a
       tool like Devel::Declare	to create full-blown new keywords in Perl.

       o   Stevan Little <>

       o   Dave	Rolsky <>

       o   Jesse Luehrs	<>

       o   Shawn M Moore <>

       o   xxxx	x<section>xx'xx	(Yuval Kogman) <>

       o   Karen Etheridge <>

       o   Florian Ragwitz <>

       o   Hans	Dieter Pearcey <>

       o   Chris Prather <>

       o   Matt	S Trout	<>

       This software is	copyright (c) 2006 by Infinity Interactive, Inc.

       This is free software; you can redistribute it and/or modify it under
       the same	terms as the Perl 5 programming	language system	itself.

perl v5.24.1	     Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass(3)


Want to link to this manual page? Use this URL:

home | help