Object-Realize-Later-0.19/0000755000175000001440000000000012270435710016026 5ustar00markovusers00000000000000Object-Realize-Later-0.19/Changes0000644000175000001440000000504512270435707017333 0ustar00markovusers00000000000000Revision history for Perl extension Object::Realize::Later. version 0.19: Fri Jan 24 11:09:06 CET 2014 Improvements: - mv t/99pod.t to xt/ and removed dependency to Test::Pod - changed documentation syntax version 0.18: Fri Jun 8 16:12:16 CEST 2007 - add Test::Pod to pre-requisits. version 0.17: Fri Jun 8 16:09:52 CEST 2007 - added t/pod.t - use oodist to generate documentation version 0.16: Sun Mar 25 17:10:24 CEST 2007 - generate pod with OODoc 0.99 - removed need for version, mkdist, mkdoc - removed README.oodoc version 0.15: Fri Jan 9 11:39:54 CET 2004 - [Renat Araslanow] found many mistakes in the docs. - [Daniel Axelrod] Realized class which can AUTOLOAD should not die on 'unknown method'. version 0.14: Tue Jul 29 2003 - [Slaven Rezic] spotted another buglet which was caused by a missed escape in generated code. version 0.13: Tue Jul 29 16:11:18 CEST 2003 - Module moved to lib/ - Documentation now uses OODoc - [Slaven Rezic] added the feature to specify a class which has a different name than its module. See new(source_module). tests in t/60module.t - forgot to include t/50again.t in the distribution 0.12 Mon Jul 7 16:20:32 CEST 2003 - [Bjoern Kriews] found a bug in $class->isa($otherclass) 0.11 Tue Jun 10 11:42:01 CEST 2003 - [Bjoern Kriews] made proxying of class methods work as well, without realization. - [Bjoern Kriews] showed that the method name can be stripped using substr/rindex much faster than by using a regex 0.10 Thu Dec 12 13:20:33 CET 2002 - Multi-Level laziness now works as well! Problem discover by [Mark Fowler] 0.09 Sat Nov 16 15:05:04 CET 2002 - Removed reference to (non-existent) Object::Realize::Proxy in man-page. [Liz Mattijsen] - Added location to warn_realization warnings [Slavan Rezic] 0.08 Wed Nov 14 10:35:18 CET 2001 - Added option `believe_caller' 0.07 Thu Sep 20 17:44:19 CEST 2001 - Added requirement for Scalar::Util to Makefile.PL spotted by [Andreas Marcel Riechert] - Added README requested by [Andreas Marcel Riechert] 0.06 Thu Sep 20 16:54:47 CEST 2001 - Fixed serious bug in AUTOLOAD: forgot to consume one arg. 0.05 Wed Sep 19 14:22:15 CEST 2001 - Removed need for Memoize 0.02 Mon Sep 10 14:59:22 CEST 2001 - Added willRealize() to question what an object will become. - option `warn' now called `warn_realization'. - When 'becomes' specifies code, the reference was stringified. Fixed and tests added. 0.01 Sun Aug 12 12:00:46 2001 - original version; created by h2xs 1.20 with options -AX Object::Realize::Later Object-Realize-Later-0.19/META.yml0000644000175000001440000000076512270435710017307 0ustar00markovusers00000000000000--- abstract: 'Delayed realization of objects' author: - 'Mark Overmeer ' build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120630' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Object-Realize-Later no_index: directory: - t - inc requires: Scalar::Util: 0 version: 0.19 Object-Realize-Later-0.19/xt/0000755000175000001440000000000012270435710016461 5ustar00markovusers00000000000000Object-Realize-Later-0.19/xt/99pod.t0000644000175000001440000000041212270435707017615 0ustar00markovusers00000000000000#!/usr/bin/perl use warnings; use strict; use Test::More; BEGIN { eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; plan skip_all => "devel home uses OODoc" if $ENV{MARKOV_DEVEL}; } all_pod_files_ok(); Object-Realize-Later-0.19/Makefile.PL0000644000175000001440000000121412270435707020004 0ustar00markovusers00000000000000use ExtUtils::MakeMaker; require 5.008; WriteMakefile ( NAME => 'Object::Realize::Later' , VERSION => '0.19' , PREREQ_PM => { Scalar::Util => 0.0 } , AUTHOR => 'Mark Overmeer ' , ABSTRACT => 'Delayed realization of objects' , LICENSE => 'perl' ); ### used by oodist during production of distribution sub MY::postamble { <<'__POSTAMBLE' } # for DIST RAWDIR = ../public_html/orl/raw DISTDIR = ../public_html/orl/source LICENSE = artistic # for POD FIRST_YEAR = 2001 EMAIL = perl@overmeer.net WEBSITE = http://perl.overmeer.net/orl/ __POSTAMBLE Object-Realize-Later-0.19/README0000644000175000001440000000152012270435707016712 0ustar00markovusers00000000000000=== README for Object-Realize-Later version 0.19 = Generated on Fri Jan 24 11:09:11 2014 by OODoc 2.01 There are various ways to install this module: (1) if you have a command-line, you can do: perl -MCPAN -e 'install ' (2) if you use Windows, have a look at http://ppm.activestate.com/ (3) if you have downloaded this module manually (as root/administrator) gzip -d Object-Realize-Later-0.19.tar.gz tar -xf Object-Realize-Later-0.19.tar cd Object-Realize-Later-0.19 perl Makefile.PL make # optional make test # optional make install For usage, see the included manual-pages or http://search.cpan.org/dist/Object-Realize-Later-0.19/ Please report problems to http://rt.cpan.org/Dist/Display.html?Queue=Object-Realize-Later Object-Realize-Later-0.19/lib/0000755000175000001440000000000012270435710016574 5ustar00markovusers00000000000000Object-Realize-Later-0.19/lib/Object/0000755000175000001440000000000012270435710020002 5ustar00markovusers00000000000000Object-Realize-Later-0.19/lib/Object/Realize/0000755000175000001440000000000012270435710021375 5ustar00markovusers00000000000000Object-Realize-Later-0.19/lib/Object/Realize/Later.pm0000644000175000001440000001064312270435707023014 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. package Object::Realize::Later; our $VERSION = '0.19'; use Carp; use Scalar::Util 'weaken'; use warnings; use strict; no strict 'refs'; my $named = 'ORL_realization_method'; my $helper = 'ORL_fake_realized'; sub init_code($) { my $args = shift; <{class}; require $args->{source_module}; my \$$helper = bless {}, '$args->{becomes}'; INIT_CODE } sub isa_code($) { my $args = shift; <SUPER::isa(\$what); # real dependency? \$$helper\->isa(\$what); } ISA_CODE } sub can_code($) { my $args = shift; my $becomes = $args->{becomes}; <SUPER::can(\$method) and return \$func; \$func = \$$helper\->can(\$method) or return; # wrap func() to trigger load if needed. sub { ref \$thing ? \$func->(\$thing->forceRealize, \@_) : \$func->(\$thing, \@_) }; } CAN_CODE } sub AUTOLOAD_code($) { my $args = shift; <<'CODE1' . ($args->{believe_caller} ? '' : <can(\$call) || \$$helper->can('AUTOLOAD')) { use Carp; croak "Unknown method \$call called"; } NOT_BELIEVE # forward as class method if required shift and return $args->{becomes}->\$call( \@_ ) unless ref \$_[0]; \$_[0]->forceRealize; my \$made = shift; \$made->\$call(\@_); } CODE2 } sub realize_code($) { my $args = shift; my $pkg = __PACKAGE__; my $argspck= join "'\n , '", %$args; <{warn_realization} ? <<'WARN' : '') .<realize ( ref_object => \\\${_[0]} , caller => [ caller 1 ] , '$argspck' ); } REALIZE_CODE } sub will_realize_code($) { my $args = shift; my $becomes = $args->{becomes}; <realizationOf($object); if(defined $already && ref $already ne ref $object) { if($args{warn_realize_again}) { my (undef, $filename, $line) = @{$args{caller}}; warn "Attempt to realize object again: old reference caught at $filename line $line.\n" } return ${$args{ref_object}} = $already; } my $loaded = ref $realize ? $realize->($object) : $object->$realize; warn "Load produces a ".ref($loaded) . " where a $args{becomes} is expected.\n" unless $loaded->isa($args{becomes}); ${$args{ref_object}} = $loaded; $class->realizationOf($object, $loaded); } my %realization; sub realizationOf($;$) { my ($class, $object) = (shift, shift); my $unique = "$object"; if(@_) { $realization{$unique} = shift; weaken $realization{$unique}; } $realization{$unique}; } sub import(@) { my ($class, %args) = @_; confess "Require 'becomes'" unless $args{becomes}; confess "Require 'realize'" unless $args{realize}; $args{class} = caller; $args{warn_realization} ||= 0; $args{warn_realize_again} ||= 0; $args{source_module} ||= $args{becomes}; # A reference to code will stringify at the eval below. To solve # this, it is tranformed into a call to a named subroutine. if(ref $args{realize} eq 'CODE') { my $named_method = "$args{class}::$named"; *{$named_method} = $args{realize}; $args{realize} = $named_method; } # Produce the code my $args = \%args; my $eval = init_code($args) . isa_code($args) . can_code($args) . AUTOLOAD_code($args) . realize_code($args) . will_realize_code($args) ; #warn $eval; # Install the code eval $eval; die $@ if $@; 1; } 1; Object-Realize-Later-0.19/lib/Object/Realize/Later.pod0000644000175000001440000003143112270435707023160 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Object::Realize::Later - Delayed creation of objects =head1 SYNOPSIS package MyLazyObject; use Object::Realize::Later becomes => 'MyRealObject', realize => 'load'; =head1 DESCRIPTION The C class helps with implementing transparent on demand realization of object data. This is related to the tricks on autoloading of data, the lesser known cousin of autoloading of functionality. On demand realization is all about performance gain. Why should you spent costly time on realizing an object, when the data on the object is never (or not yet) used? In interactive programs, postponed realization may boost start-up: the realization of objects is triggered by the use, so spread over time. =head1 METHODS =head2 Construction =over 4 =item B(Object::Realize::Later %options) When you invoke (C) the C package, it will add a set of methods to your package (see section L). -Option --Default becomes believe_caller realize source_module warn_realization warn_realize_again =over 2 =item becomes => CLASS Which type will this object become after realization. =item believe_caller => BOOLEAN When a method is called on the un-realized object, the AUTOLOAD checks whether this resolves the need. If not, the realization is not done. However, when realization may result in an object that extends the functionality of the class specified with C, this check must be disabled. In that case, specify true for this option. =item realize => METHOD|CODE How will transform. If you specify a CODE reference, then this will be called with the lazy-object as first argument, and the requested method as second. After realization, you may still have your hands on the lazy object on various places. Be sure that your realization method is coping with that, for instance by using L. See examples below. =item source_module => CLASS if the class (a package) is included in a file (module) with a different name, then use this argument to specify the file name. The name is expected to be the same as in the C call which would load it. =item warn_realization => BOOLEAN Print a warning message when the realization starts. This is for debugging purposes. =item warn_realize_again => BOOLEAN When an object is realized, the original object -which functioned as a stub- is reconstructed to work as proxy to the realized object. This option will issue a warning when that proxy is used, which means that somewhere in your program there is a variable still holding a reference to the stub. This latter is not problematic at all, although it slows-down each method call. =back =back =head2 Added to YOUR class =over 4 =item $obj-EB() When a method is called which is not available for the lazy object, the AUTOLOAD is called. =item $obj-EB($method) =item Object::Realize::Later-EB($method) Is the specified $method available for the lazy or the realized version of this object? It will return the reference to the code. example: MyLazyObject->can('lazyWork') # true MyLazyObject->can('realWork') # true my $lazy = MyLazyObject->new; $lazy->can('lazyWork'); # true $lazy->can('realWork'); # true =item $obj-EB() You can force the load by calling this method on your object. It returns the realized object. =item Object::Realize::Later-EB($class) Is this object a (sub-)class of the specified $class or can it become a (sub-)class of $class. example: MyLazyObject->isa('MyRealObject') # true MyLazyObject->isa('SuperClassOfLazy'); # true MyLazyObject->isa('SuperClassOfReal'); # true my $lazy = MyLazyObject->new; $lazy->isa('MyRealObject'); # true $lazy->isa('SuperClassOfLazy'); # true $lazy->isa('SuperClassOfReal'); # true =item $obj-EB() Returns which class will be the realized to follow-up this class. =back =head2 Object::Realize::Later internals The next methods are not exported to the class where the `use' took place. These methods implement the actual realization. =over 4 =item Object::Realize::Later-EB(%options) The %options used for C are the values after the class name with C. So this routine implements the actual option parsing. It generates code dynamically, which is then evaluated in the callers name-space. =item Object::Realize::Later-EB( $object, [$realized] ) Returns the $realized version of $object, optionally after setting it first. When the method returns C, the realization has not yet taken place or the realized object has already been removed again. =item Object::Realize::Later-EB(%options) This method is called when a C<$object->forceRealize()> takes place. It checks whether the realization has been done already (is which case the realized object is returned) =back =head1 DETAILS =head2 About lazy loading There are two ways to implement lazy behaviour: you may choose to check whether you have realized the data in each method which accesses the data, or use the autoloading of data trick. An implementation of the first solution is: sub realize { my $self = shift; return $self unless $self->{_is_realized}; # read the data from file, or whatever $self->{data} = ....; $self->{_is_realized} = 1; $self; } sub getData() { my $self = shift; return $self->realize->{data}; } The above implementation is error-prone, where you can easily forget to call L. The tests cannot cover all ordenings of method-calls to detect the mistakes. The I uses autoloading, and is supported by this package. First we create a stub-object, which will be transformable into a realized object later. This transformation is triggered by AUTOLOAD. This stub-object may contain some methods from the realized object, to reduce the need for realization. The stub will also contain some information which is required for the creation of the real object. C solves the inheritance problems (especially the L and L methods) and supplies the AUTOLOAD method. Class methods which are not defined in the stub object are forwarded as class methods without realization. =head2 Traps Be aware of dangerous traps in the current implementation. These problems appear by having multiple references to the same delayed object. Depending on how the realization is implemented, terrible things can happen. The two versions of realization: =over 4 =item * by reblessing This is the safe version. The realized object is the same object as the delayed one, but reblessed in a different package. When multiple references to the delayed object exists, they will all be updated at the same, because the bless information is stored within the refered variable. =item * by new instance This is the nicest way of realization, but also quite more dangerous. Consider this: package Delayed; use Object::Realize::Later becomes => 'Realized', realize => 'load'; sub new($) {my($class,$v)=@_; bless {label=>$v}, $class} sub setLabel($) {my $self = shift; $self->{label} = shift} sub load() {$_[0] = Realized->new($_[0]->{label}) } package Realized; # file Realized.pm or use use(source_module) sub new($) {my($class,$v)=@_; bless {label=>$v}, $class} sub setLabel($) {my $self = shift; $self->{label} = shift} sub getLabel() {my $self = shift; $self->{label}} package main; my $original = Delayed->new('original'); my $copy = $original; print $original->getLabel; # prints 'original' print ref $original; # prints 'Realized' print ref $copy; # prints 'Delayed' $original->setLabel('changed'); print $original->getLabel; # prints 'changed' print $copy->getLabel; # prints 'original' =back =head2 Examples =head3 Example 1 In the first example, we delay-load a message. On the moment the message is defined, we only take the location. When the data of the message is taken (header or body), the data is autoloaded. package Mail::Message::Delayed; use Object::Realize::Later ( becomes => 'Mail::Message::Real' , realize => 'loadMessage' ); sub new($) { my ($class, $file) = @_; bless { filename => $file }, $class; } sub loadMessage() { my $self = shift; Mail::Message::Real->new($self->{filename}); } In the main program: package main; use Mail::Message::Delayed; my $msg = Mail::Message::Delayed->new('/home/user/mh/1'); $msg->body->print; # this will trigger autoload. =head3 Example 2 Your realization may also be done by reblessing. In that case to change the type of your object into a different type which stores the same information. Is that right? Are you sure? For simple cases, this may be possible: package Alive; use Object::Realize::Later becomes => 'Dead', realize => 'kill'; sub new() {my $class = shift; bless {@_}, $class} sub jump() {print "Jump!\n"} sub showAntlers() {print "Fight!\n"} sub kill() {bless(shift, 'Dead')} package Dead; sub takeAntlers() {...} In the main program: my $deer = Alive->new(Animal => 'deer'); my $trophy = $deer->takeAntlers(); In this situation, the object (reference) is not changed but is I. There is no danger that the un-realized version of the object is kept somewhere: all variable which know about this partical I see the change. =head3 Example 3 This module is especially usefull for larger projects, which there is a need for speed or memory reduction. In this case, you may have an extra overview on which objects have been realized (transformed), and which not. This example is taken from the MailBox modules: The L module tries to boost the access-time to a folder. If you only need the messages of the last day, why shall all be read? So, MailBox only creates an invertory of messages at first. It takes the headers of all messages, but leaves the body (content) of the message in the file. In MailBox' case, the L-object has the choice between a number of L's, one of which has only be prepared to read the body when needed. A code snippet: package Mail::Message; sub new($$) { my ($class, $head, $body) = @_; my $self = bless {head => $head, body => $body}, $class; $body->message($self); # tell body about the message } sub head() { shift->{head} } sub body() { shift->{body} } sub loadBody() { my $self = shift; my $body = $self->body; # Catch re-invocations of the loading. If anywhere was still # a reference to the old (unrealized) body of this message, we # return the new-one directly. return $body unless $body->can('forceRealize'); # Load the body (change it to anything which really is of # the promised type, or a sub-class of it. my ($lines, $size) = .......; # get the data $self->{body} = Mail::Message::Body::Lines ->new($lines, $size, $self); # Return the realized object. return $self->{body}; } package Mail::Message::Body::Lines; use base 'Mail::Message::Body'; sub new($$$) { my ($class, $lines, $size, $message) = @_; bless { lines => $lines, size => $size , message => $message }, $class; } sub size() { shift->{size} } sub lines() { shift->{lines} } sub message() { shift->{message); package Mail::Message::Body::Delayed; use Object::Realize::Later becomes => 'Mail::Message::Body', realize => sub {shift->message->loadBody}; sub new($) { my ($class, $size) = @_; bless {size => $size}, $class; } sub size() { shift->{size} } sub message(;$) { my $self = shift; @_ ? ($self->{message} = shift) : $self->{messages}; } package main; use Mail::Message; use Mail::Message::Body::Delayed; my $body = Mail::Message::Body::Delayed->new(42); my $message = Mail::Message->new($head, $body); print $message->size; # will not trigger realization! print $message->can('lines'); # true, but no realization yet. print $message->lines; # realizes automatically. =head1 SEE ALSO This module is part of Object-Realize-Later distribution version 0.19, built on January 24, 2014. Website: F =head1 LICENSE Copyrights 2001-2014 by [Mark Overmeer ]. For other contributors see Changes. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F Object-Realize-Later-0.19/MANIFEST0000644000175000001440000000100712270435710017155 0ustar00markovusers00000000000000Changes MANIFEST Makefile.PL README lib/Object/Realize/Later.pm lib/Object/Realize/Later.pod t/10isa.t t/20can.t t/30realize.t t/40autoload.t t/41autoload.t t/50again.t t/60module.t t/testmods/A.pm t/testmods/A/B.pm t/testmods/C.pm t/testmods/C/D.pm t/testmods/C/D/E.pm t/testmods/C/G.pm t/testmods/C/G/H.pm t/testmods/I.pm t/testmods/J.pm xt/99pod.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Object-Realize-Later-0.19/t/0000755000175000001440000000000012270435710016271 5ustar00markovusers00000000000000Object-Realize-Later-0.19/t/50again.t0000644000175000001440000000134112270435707017707 0ustar00markovusers00000000000000#!/usr/bin/perl -w # # Test re-realization # use strict; use Test; use lib 't', '.', 't/testmods', 'testmods'; use C::D::E; BEGIN { plan tests => 8 } my $warntxt; sub catchwarn {$warntxt = "@_"}; # Autoload via C::D because of request from A::B my $obj = C::D->new; my $copy = $obj; { local $SIG{__WARN__} = \&catchwarn; ok($obj->a_b eq 'a_b'); # triggers autoload } ok($warntxt, qr/^Realization of C::D /); ok(ref $obj eq 'A::B'); ok(ref $copy eq 'C::D'); { local $SIG{__WARN__} = \&catchwarn; ok($copy->a_b eq 'a_b'); # triggers autoload for the second time } #warn "$warntxt\n"; ok($warntxt =~ /^Attempt to realize object again: old reference caught at/); ok(ref $copy eq 'A::B'); ok($copy eq $obj); Object-Realize-Later-0.19/t/60module.t0000644000175000001440000000041112270435707020113 0ustar00markovusers00000000000000#!/usr/bin/perl -w # -*- perl -*- # By Slavan Rezic 2003-07-29 use strict; use Test; use lib "t/testmods"; use I; BEGIN { plan tests => 3 } my $i_obj = I->new; ok(ref $i_obj, "I"); ok($i_obj->a_method, 42); ok(ref $i_obj, "Another::Class"); Object-Realize-Later-0.19/t/10isa.t0000644000175000001440000000133612270435707017404 0ustar00markovusers00000000000000#!/usr/bin/perl -w # # Test the isa() relations # use strict; use Test; use lib 't', '.', 't/testmods', 'testmods'; use C::D::E; BEGIN { plan tests => 23 } my $obj = C::D->new; ok($obj); ok($obj->isa('C')); ok(not $obj->isa('C::D::E')); ok($obj->isa('A::B')); ok($obj->isa('A')); ok(not $obj->isa('GarbleBlaster')); ok(C::D::E->isa('C::D::E')); ok(C::D::E->isa('C::D')); ok(C::D::E->isa('C')); ok(C::D->isa('C::D')); ok(C::D->isa('C')); ok(C->isa('C')); ok(not C::D->isa('GarbleBlaster')); ok(C::D::E->isa('A::B')); ok(C::D::E->isa('A')); ok(C::D->isa('A::B')); ok(C::D->isa('A')); ok(not C->isa('A::B')); ok(not C->isa('A')); ok(not A::B->isa('C::D')); ok(not A::B->isa('C')); ok(not A->isa('C::D')); ok(not A->isa('C')); Object-Realize-Later-0.19/t/30realize.t0000644000175000001440000000154512270435707020267 0ustar00markovusers00000000000000#!/usr/bin/perl -w # # Test the releaze() # use strict; use Test; use lib 't', '.', 't/testmods', 'testmods'; use C::D::E; BEGIN { plan tests => 15 } my $warntxt; sub catchwarn {$warntxt = "@_"}; my $obj = C::D->new; ok($obj); ok(ref $obj eq 'C::D'); ok(not defined $warntxt); my $new; { local $SIG{__WARN__} = \&catchwarn; $new = $obj->forceRealize; } ok($new); ok($warntxt, qr/^Realization of C::D /); ok(ref $obj eq 'A::B'); # passed new ref back? $obj = C::D::E->new; ok($obj); undef $warntxt; { local $SIG{__WARN__} = \&catchwarn; $new = $obj->forceRealize; } ok($new); ok($warntxt, qr/^Realization of C::D::E /); ok(ref $obj eq 'A::B'); ok(not defined $obj->can('C::D::E')); ok(not defined $obj->can('C::D')); ok(not defined $obj->can('C')); # test class methods (simple and proxied) ok( C::D->c_d eq 'c_d' ); ok( C::D->a_b eq 'a_b' ); Object-Realize-Later-0.19/t/testmods/0000755000175000001440000000000012270435710020133 5ustar00markovusers00000000000000Object-Realize-Later-0.19/t/testmods/A/0000755000175000001440000000000012270435710020313 5ustar00markovusers00000000000000Object-Realize-Later-0.19/t/testmods/A/B.pm0000644000175000001440000000046312270435707021043 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. use strict; use warnings; package A::B; our $VERSION = '0.19'; use base 'A'; sub a_b() {'a_b'} 1; Object-Realize-Later-0.19/t/testmods/C/0000755000175000001440000000000012270435710020315 5ustar00markovusers00000000000000Object-Realize-Later-0.19/t/testmods/C/G.pm0000644000175000001440000000071412270435707021051 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. package C::G; our $VERSION = '0.19'; use base 'C'; use Object::Realize::Later ( becomes => 'A::B' , realize => sub { bless(shift, 'A::B') } , warn_realization => 1 , warn_realize_again => 1 ); sub c_g() {'c_g'} 1; Object-Realize-Later-0.19/t/testmods/C/D/0000755000175000001440000000000012270435710020500 5ustar00markovusers00000000000000Object-Realize-Later-0.19/t/testmods/C/D/E.pm0000644000175000001440000000047512270435707021236 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. use warnings; use strict; package C::D::E; our $VERSION = '0.19'; use base 'C::D'; sub c_d_e() {'c_d_e'} 1; Object-Realize-Later-0.19/t/testmods/C/D.pm0000644000175000001440000000072312270435707021046 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. package C::D; our $VERSION = '0.19'; use base 'C'; use Object::Realize::Later ( becomes => 'A::B' , realize => 'load' , warn_realization => 1 , warn_realize_again => 1 ); sub load() { bless {}, 'A::B' } sub c_d() {'c_d'} 1; Object-Realize-Later-0.19/t/testmods/C/G/0000755000175000001440000000000012270435710020503 5ustar00markovusers00000000000000Object-Realize-Later-0.19/t/testmods/C/G/H.pm0000644000175000001440000000047512270435707021244 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. use warnings; use strict; package C::G::H; our $VERSION = '0.19'; use base 'C::G'; sub c_g_h() {'c_g_h'} 1; Object-Realize-Later-0.19/t/testmods/A.pm0000644000175000001440000000043512270435707020661 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. use strict; use warnings; package A; our $VERSION = '0.19'; sub a() {'a'} 1; Object-Realize-Later-0.19/t/testmods/C.pm0000644000175000001440000000055112270435707020662 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. use strict; use warnings; package C; our $VERSION = '0.19'; use overload '""' => sub { ref(shift) }; sub new() { bless {}, shift } sub c() { 'c' } 1; Object-Realize-Later-0.19/t/testmods/I.pm0000644000175000001440000000064612270435707020675 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. package I; our $VERSION = '0.19'; use Object::Realize::Later realize => sub { bless {}, 'Another::Class' }, becomes => 'Another::Class', source_module => 'J'; sub new { bless {}, shift } 1; Object-Realize-Later-0.19/t/testmods/J.pm0000644000175000001440000000047212270435707020673 0ustar00markovusers00000000000000# Copyrights 2001-2014 by [Mark Overmeer ]. # For other contributors see Changes. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.01. package J; our $VERSION = '0.19'; package Another::Class; our $VERSION = '0.19'; sub a_method { 42 } 1; Object-Realize-Later-0.19/t/41autoload.t0000644000175000001440000000237412270435707020447 0ustar00markovusers00000000000000#!/usr/bin/perl -w # # Test the autoloading() where becomes => CODE # use strict; use Test; use lib 't', '.', 't/testmods', 'testmods'; use C::G::H; BEGIN { plan tests => 17 } my $warntxt; sub catchwarn {$warntxt = "@_"}; # Autoload via C::G because of request from A::B my $obj = C::G->new; ok($obj->c_g eq 'c_g'); ok($obj->c eq 'c' ); { local $SIG{__WARN__} = \&catchwarn; ok($obj->a_b eq 'a_b'); # triggers autoload } ok($warntxt, qr/^Realization of C::G /); ok(ref $obj eq 'A::B'); # Autoload via C::G::H because of request from A::B $obj = C::G::H->new; ok($obj->c_g_h eq 'c_g_h'); ok($obj->c_g eq 'c_g'); ok($obj->c eq 'c' ); { local $SIG{__WARN__} = \&catchwarn; ok($obj->a_b eq 'a_b'); # triggers autoload } ok($warntxt, qr/^Realization of C::G::H /); ok(ref $obj eq 'A::B'); # Autoload via C::G because of request from A $obj = C::G->new; { local $SIG{__WARN__} = \&catchwarn; ok($obj->a eq 'a'); # triggers autoload } ok($warntxt, qr/^Realization of C::G /); ok(ref $obj eq 'A::B'); # Autoload via C::G::H because of request from A $obj = C::G::H->new; { local $SIG{__WARN__} = \&catchwarn; ok($obj->a eq 'a'); # triggers autoload } ok($warntxt, qr/^Realization of C::G::H /); ok(ref $obj eq 'A::B'); Object-Realize-Later-0.19/t/40autoload.t0000644000175000001440000000237612270435707020450 0ustar00markovusers00000000000000#!/usr/bin/perl -w # # Test the autoloading() where becomes => STRING # use strict; use Test; use lib 't', '.', 't/testmods', 'testmods'; use C::D::E; BEGIN { plan tests => 17 } my $warntxt; sub catchwarn {$warntxt = "@_"}; # Autoload via C::D because of request from A::B my $obj = C::D->new; ok($obj->c_d eq 'c_d'); ok($obj->c eq 'c' ); { local $SIG{__WARN__} = \&catchwarn; ok($obj->a_b eq 'a_b'); # triggers autoload } ok($warntxt, qr/^Realization of C::D /); ok(ref $obj eq 'A::B'); # Autoload via C::D::E because of request from A::B $obj = C::D::E->new; ok($obj->c_d_e eq 'c_d_e'); ok($obj->c_d eq 'c_d'); ok($obj->c eq 'c' ); { local $SIG{__WARN__} = \&catchwarn; ok($obj->a_b eq 'a_b'); # triggers autoload } ok($warntxt, qr/^Realization of C::D::E /); ok(ref $obj eq 'A::B'); # Autoload via C::D because of request from A $obj = C::D->new; { local $SIG{__WARN__} = \&catchwarn; ok($obj->a eq 'a'); # triggers autoload } ok($warntxt, qr/^Realization of C::D /); ok(ref $obj eq 'A::B'); # Autoload via C::D::E because of request from A $obj = C::D::E->new; { local $SIG{__WARN__} = \&catchwarn; ok($obj->a eq 'a'); # triggers autoload } ok($warntxt, qr/^Realization of C::D::E /); ok(ref $obj eq 'A::B'); Object-Realize-Later-0.19/t/20can.t0000644000175000001440000000173112270435707017371 0ustar00markovusers00000000000000#!/usr/bin/perl -w # # Test the can() relations # use strict; use Test; use lib 't', '.', 't/testmods', 'testmods'; use C::D::E; BEGIN { plan tests => 26 } my $obj = C::D->new; ok($obj); ok(defined $obj->can('c')); ok(not $obj->can('c_d_e')); ok(defined $obj->can('a_b')); ok(defined $obj->can('a')); ok(defined C::D::E->can('c_d_e')); ok(defined C::D::E->can('c_d')); ok(defined C::D::E->can('c')); ok(defined C::D->can('c_d')); ok(defined C::D->can('c')); ok(defined C->can('c')); ok(defined C::D::E->can('a_b')); ok(defined C::D::E->can('a')); ok(defined C::D->can('a_b')); ok(defined C::D->can('a')); ok(not defined C->can('a_b')); ok(not defined C->can('a')); ok(not defined A::B->can('c_d')); ok(not defined A::B->can('c')); ok(not defined A->can('c_d')); ok(not defined A->can('c')); ok(defined C::D->can('willRealize')); ok(defined C::D::E->can('willRealize')); ok(!defined C->can('willRealize')); ok(C::D->willRealize eq 'A::B'); ok(C::D::E->willRealize eq 'A::B'); Object-Realize-Later-0.19/META.json0000644000175000001440000000157112270435710017453 0ustar00markovusers00000000000000{ "abstract" : "Delayed realization of objects", "author" : [ "Mark Overmeer " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120630", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Object-Realize-Later", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Scalar::Util" : "0" } } }, "release_status" : "stable", "version" : "0.19" }