package Class::Lego::Myself; use 5.006; use strict; use warnings; our $VERSION = '0.003'; use Sub::Exporter -setup => { exports => [ qw(give_my_self) ], groups => { default => [ qw(give_my_self) ], } }; use Scalar::Defer 0.13 (); use Sub::Install (); use Carp qw( croak ); sub give_my_self { my $self = shift; my $class = ref $self || $self; my $options = shift || {}; my $default = $options->{default} || Scalar::Defer::lazy(sub { $class->new }); if ( Scalar::Defer::is_deferred($default) ) { # ok } elsif ( ref $default eq 'CODE' ) { # given a code, defer it $default = &Scalar::Defer::lazy($default); } else { croak "default should be a code ref"; } my $find_my_self = make_find_my_self( $default ); Sub::Install::install_sub({ code => $find_my_self, into => $class, as => 'find_my_self', }); # my $get_default = sub { return $default }; # Sub::Install::install_sub({ # code => $get_default, # into => $class, # as => 'get_default', # }); } sub make_find_my_self { my $default_object = shift; return sub { my $self = shift; if ( !ref $self ) { $self = $default_object; } if ( wantarray ) { return $self, @_; } else { return $self; } }; } "me, myself and Zellweger";