1#======================================================================== 2# 3# Badger::Factory 4# 5# DESCRIPTION 6# Factory module for loading and instantiating other modules. 7# 8# NOTE 9# This module has grown organically to fit a number of (possibly 10# conflicting) needs. It needs to be completely refactored, and 11# probably split into a number of different factory modules. The 12# TT3 code on which this was originally based had separate base class 13# factory modules for modules (that just got loaded), objects (that 14# got loaded and instantiated) and single objects (that got loaded, 15# created and cached). With hindsight, it was a mistake to try and 16# cram all that functionality into one module. It should be separated 17# into a base class module/API and a number of specialised subclasses. 18# 19# AUTHOR 20# Andy Wardley <abw@wardley.org> 21# 22#======================================================================== 23 24package Badger::Factory; 25 26use Badger::Debug ':dump'; 27use Badger::Class 28 version => 0.01, 29 debug => 0, 30 base => 'Badger::Prototype Badger::Exporter', 31 import => 'class', 32 utils => 'plural blessed textlike dotid camel_case', 33 words => 'ITEM ITEMS ISA', 34 constants => 'PKG ARRAY HASH REFS ONCE DEFAULT LOADED', 35 constant => { 36 OBJECT => 'object', 37 FOUND => 'found', 38 FOUND_REF => 'found_ref', 39 PATH_SUFFIX => '_PATH', 40 NAMES_SUFFIX => '_NAMES', 41 DEFAULT_SUFFIX => '_DEFAULT', 42 }, 43 messages => { 44 no_item => 'No item(s) specified for factory to manage', 45 no_default => 'No default defined for %s factory', 46 bad_ref => 'Invalid reference for %s factory item %s: %s', 47 bad_method => qq{Can't locate object method "%s" via package "%s" at %s line %s}, 48 }; 49 50our $RUNAWAY = 0; 51our $AUTOLOAD; 52 53*init = \&init_factory; 54 55 56sub init_factory { 57 my ($self, $config) = @_; 58 my $class = $self->class; 59 my ($item, $items, $path, $map, $default); 60 61 # 'item' and 'items' can be specified as config params or we look for 62 # $ITEM and $ITEMS variables in the current package or those of any 63 # base classes. NOTE: $ITEM and $ITEMS must be in the same package 64 unless ($item = $config->{ item }) { 65 foreach my $pkg ($class->heritage) { 66 no strict REFS; 67 no warnings ONCE; 68 69 if (defined ($item = ${ $pkg.PKG.ITEM })) { 70 $items = ${ $pkg.PKG.ITEMS }; 71 last; 72 } 73 } 74 } 75 return $self->error_msg('no_item') 76 unless $item; 77 78 # use 'items' in config, or grokked from $ITEMS, or guess plural 79 $items = $config->{ items } || $items || plural($item); 80 81 my $ipath = $item.PATH_SUFFIX; 82 my $inames = $item.NAMES_SUFFIX; 83 my $idefault = $item.DEFAULT_SUFFIX; 84 85 # Merge all XXXX_PATH package vars with any 'xxxx_path' or 'path' config 86 # items. Ditto for XXXX_NAME / 'xxxx_name' / 'aka' and XXXXS/ 'xxxxs' 87 88 my @path = @$config{ path => lc $ipath }; 89 my @names = @$config{ names => lc $inames }; 90 91 $self->{ path } = $class->list_vars(uc $ipath, @path); 92 $self->{ names } = $class->hash_vars(uc $inames, @names); 93 $self->{ $items } = $class->hash_vars(uc $items, $config->{ $items }); 94 $self->{ items } = $items; 95 $self->{ item } = $item; 96 $self->{ loaded } = { }; 97 $self->{ no_cache } = defined $config->{ no_cache } # quick hack 98 ? $config->{ no_cache } 99 : $class->any_var('NO_CACHE') || 0; 100 101 # see if a 'xxxx_default' or 'default' configuration option is specified 102 # or look for the first XXXX_DEFAULT or DEFAULT package variable. 103 $default = $config->{ $idefault } 104 || $config->{ default } 105 || $class->any_var_in( uc $idefault, uc DEFAULT ); 106 if ($default) { 107 $self->debug("Setting default to $default") if DEBUG; 108 $self->{ default } = $self->{ names }->{ default } = $default; 109 } 110 111 $self->debug( 112 "Initialised $item/$items factory\n", 113 " Path: ", $self->dump_data($self->{ path }), "\n", 114 "Names: ", $self->dump_data($self->{ names }) 115 ) if DEBUG; 116 117 return $self; 118} 119 120sub path { 121 my $self = shift->prototype; 122 return @_ 123 ? ($self->{ path } = ref $_[0] eq ARRAY ? shift : [ @_ ]) 124 : $self->{ path }; 125} 126 127sub default { 128 my $self = shift->prototype; 129 return @_ 130 ? ($self->{ default } = $self->{ names }->{ default } = shift) 131 : $self->{ default }; 132} 133 134sub items { 135 my $self = shift->prototype; 136 my $items = $self->{ $self->{ items } }; 137 if (@_) { 138 my $args = ref $_[0] eq HASH ? shift : { @_ }; 139 @$items{ keys %$args } = values %$args; 140 } 141 return $items; 142} 143 144sub item { 145 my $self = shift; $self = $self->prototype unless ref $self; 146 my ($type, @args) = $self->type_args(@_); 147 148 # In most cases we're expecting $type to be a name (e.g. Table) which we 149 # lookup in the items hash, or tack onto one of the module bases in the 150 # path (e.g. Template::Plugin) to create a full module name which we load 151 # and instantiate (e.g. Template::Plugin::Table). However, the name might 152 # be explicitly mapped to a reference of some kind, or the $type passed 153 # in could already be a reference (e.g. Template::TT2::Filters allow the 154 # first argument to be a code ref or object which implements the required 155 # filtering behaviour). In which case, we bypass any name-based lookup 156 # and skip straight onto the "look what I found!" phase 157 158 return $self->found($type, $type, \@args) 159 unless textlike $type; 160 161 $type = $type . ''; # auto-stringify any textlike objects 162 163 # OK, so $type is a string. We'll also create a canonical version of the 164 # name (lower case dotted) to provide a case/syntax insensitve fallback 165 # (e.g. so "foo.bar" can match against "Foo.Bar", "Foo::Bar" and so on) 166 167 my $items = $self->{ $self->{ items } }; 168 my $canon = dotid $type; 169 170 $self->debug("Looking for '$type' or '$canon' in $self->{ items }") if DEBUG; 171# $self->debug("types: ", $self->dump_data($self->{ types })) if DEBUG; 172 173 # false but defined entry indicates the item is not found 174 return $self->not_found($type, \@args) 175 if exists $items->{ $type } 176 && not $items->{ $type }; 177 178 my $item = $items->{ $type } 179 || $items->{ $canon } 180 # TODO: this needs to be defined-or, like // 181 # Plugins can return an empty string to indicate that they 182 # do nothing. 183 # HMMM.... or does it? 184 || $self->find($type, \@args) 185# || $self->default($type, \@args) 186 || return $self->not_found($type, \@args); 187 188 $items->{ $type } = $item 189 unless $self->{ no_cache }; 190 191 return $self->found($type, $item, \@args); 192} 193 194sub type_args { 195 # Simple method to grok $type and @args from argument list. The only 196 # processing it does is to set $type to 'default' if it is undefined or 197 # false. Subclasses can re-define this to insert their own type mapping or 198 # argument munging, e.g. to inject values into the configuration params 199 # for an object 200 shift; 201 my $type = shift || DEFAULT; 202 my @args; 203 204 if (ref $type eq HASH) { 205 @args = ($type, @_); 206 $type = $type->{ type } || DEFAULT; 207 } 208 else { 209 @args = @_; 210 } 211 212 return ($type, @args); 213} 214 215sub find { 216 my $self = shift; 217 my $type = shift; 218 my $bases = $self->path; 219 my $module; 220 221 # run the type through the type map to handle any unusual capitalisation, 222 # spelling, aliases, etc. 223 $type = $self->{ names }->{ $type } || $type; 224 225 foreach my $base (@$bases) { 226 return $module 227 if $module = $self->load( $self->module_names($base, $type) ); 228 } 229 230 return undef; 231} 232 233sub load { 234 my $self = shift; 235 my $loaded = $self->{ loaded }; 236 237 foreach my $module (@_) { 238 # see if we've previously loaded a module with this name (true 239 # value) or failed to load a module (defined but false value) 240 241 if ($loaded->{ $module }) { 242 $self->debug("$module has been previously loaded") if DEBUG; 243 return $module; 244 } 245 elsif (defined $loaded->{ $module }) { 246 next; 247 } 248 249 no strict REFS; 250 $self->debug("attempting to load $module") if DEBUG; 251 252 # Some filesystems are case-insensitive (like Apple's HFS), so an 253 # attempt to load Badger::Example::foo may succeed, when the correct 254 # package name is actually Badger::Example::Foo. We double-check 255 # by looking for $VERSION or @ISA. This is a bit dodgy because we might be 256 # loading something that has no ISA. Need to cross-check with 257 # what's going on in Badger::Class _autoload() 258 259 my $loadname; 260 if ( ($loadname = class($module)->maybe_load) ) { 261 $self->debug("loaded $module") if DEBUG; 262 $loaded->{ $module } = $loadname; 263 return $module 264 } 265 266 $self->debug("failed to load $module") if DEBUG; 267 } 268 269 return undef; 270} 271 272 273sub found { 274 my ($self, $type, $item, $args) = @_; 275 276 if (ref $item) { 277 # if it's a reference we found then forward it onto the appropriate 278 # method, e.g found_array(), found_hash(), found_code(). Fall back 279 # on found_ref() 280 my $iref = blessed($item) 281 ? OBJECT 282 : lc ref $item; 283 284 $self->debug( 285 "Looking for handler methods: ", 286 FOUND,'_'.$iref, "() or ", 287 FOUND_REF, "()" 288 ) if DEBUG; 289 290 my $method 291 = $self->can(FOUND . '_' . $iref) 292 || $self->can(FOUND_REF) 293 || return $self->error_msg( bad_ref => $self->{ item }, $type, $iref ); 294 295 $item = $method->($self, $type, $item, $args); 296 } 297 else { 298 # otherwise it's the name of a module 299 $item = $self->found_module($type, $item, $args); 300 } 301 302 # NOTE: an item can be defined but false, e.g. a Template::Plugin which 303 # return '' from its new() method to indicate it does nothing objecty 304 return unless defined $item; 305 306 $self->debug("Found result: $type => $item") if DEBUG; 307 308 # TODO: what about caching result? Do we always leave that to subclasses? 309 return $self->result($type, $item, $args); 310} 311 312sub found_module { 313 # This method is called when a module name is found, either by being 314 # predefined in the factory entry table, or loaded on demand from disk. 315 # It ensures the module is loaded and and instantiates an object from the 316 # class name 317 my ($self, $type, $module, $args) = @_; 318 $self->debug("Found module: $type => $module") if DEBUG; 319 $self->{ loaded }->{ $module } ||= class($module)->load; 320 return $self->construct($type, $module, $args); 321} 322 323sub found_array { 324 # This method is called when an ARRAY reference is found. We assume that 325 # the first item is the module name (which needs to be loaded) and the 326 # second item is the class name (which needs to be instantiated). 327 my ($self, $type, $item, $args) = @_; 328 my ($module, $class) = @$item; 329 $self->{ loaded }->{ $module } ||= class($module)->load; 330 return $self->construct($type, $class, $args); 331} 332 333sub not_found { 334 my ($self, $type, @args) = @_; 335 336 return $type eq DEFAULT 337 ? $self->error_msg( no_default => $self->{ item } ) 338 : $self->error_msg( not_found => $self->{ item }, $type ); 339} 340 341sub construct { 342 my ($self, $type, $class, $args) = @_; 343 $self->debug("constructing class: $type => $class") if DEBUG; 344 return $class->new(@$args); 345} 346 347sub module_names { 348 my $self = shift; 349 my @bits = 350 map { camel_case($_) } 351 map { split /[\.]+/ } @_; 352 353 return ( 354 join( PKG, map { ucfirst $_ } @bits ), 355 join( PKG, @bits ) 356 ); 357} 358 359 360sub can { 361 my ($self, $name) = @_; 362 363 # upgrade class methods to calls on prototype 364 $self = $self->prototype unless ref $self; 365 366 # NOTE: this method can get called before we've called init_factory() 367 # to define the item/items members, so we tread carefully. 368 if ($self->{ item } && $self->{ item } eq $name) { 369 return $self->SUPER::can('item'); 370 } 371 elsif ($self->{ items } && $self->{ items } eq $name) { 372 return $self->SUPER::can('items'); 373 } 374 else { 375 return $self->SUPER::can($name); 376 } 377} 378 379sub result { 380 $_[2]; 381} 382 383sub AUTOLOAD { 384 my ($self, @args) = @_; 385 my ($name) = ($AUTOLOAD =~ /([^:]+)$/ ); 386 return if $name eq 'DESTROY'; 387 388 $self->debug("AUTOLOAD $name") if DEBUG; 389 390 local $RUNAWAY = $RUNAWAY; 391 $self->error("AUTOLOAD went runaway on $name") 392 if ++$RUNAWAY > 10; 393 394 # upgrade class methods to calls on prototype 395 $self = $self->prototype unless ref $self; 396 397 $self->debug("factory item: $self->{ item }") if DEBUG; 398 399 if ($name eq $self->{ item }) { 400 $self->class->method( $name => $self->can('item') ); 401 } 402 elsif ($name eq $self->{ items }) { 403 $self->class->method( $name => $self->can('items') ) 404 } 405 elsif (my $item = $self->try( item => $name, @args )) { 406 return $item; 407 } 408 else { 409 my ($pkg, $file, $line) = caller; 410 my $class = ref $self || $self; 411 die $self->message( bad_method => $name, $class, $file, $line ), "\n"; 412 } 413 414 # should be installed now 415 $self->$name(@args); 416} 417 418 4191; 420 421__END__ 422 423=head1 NAME 424 425Badger::Factory - base class factory module 426 427=head1 SYNOPSIS 428 429This module is designed to be subclassed to create factory classes that 430automatically load modules and instantiate objects on demand. 431 432 package My::Widgets; 433 use base 'Badger::Factory'; 434 435 # tell the base class factory what we create 436 our $ITEM = 'widget'; 437 our $ITEMS = 'widgets'; 438 439 # define module search path for widgets 440 our $WIDGET_PATH = ['My::Widget', 'Your::Widget']; 441 442 # lookup table for any non-standard spellings/capitalisations/paths 443 our $WIDGETS = { 444 url => 'My::Widget::URL', # non-standard capitalisation 445 color => 'My::Widget::Colour', # different spelling 446 amp => 'Nigels::Amplifier', # different path 447 }; 448 449You can then use it like this: 450 451 use My::Widgets; 452 453 # class methods (note: widget() is singular) 454 $w = My::Widgets->widget( foo => { msg => 'Hello World' } ); 455 456 # same as: 457 use My::Widget::Foo; 458 $w = My::Widget::Foo({ msg => 'Hello World' }); 459 460 # add/update widgets lookup table (note: widgets() is plural) 461 My::Widgets->widgets( 462 extra => 'Another::Widget::Module', 463 super => 'Golly::Gosh', 464 ); 465 466 # now load and instantiate new widget modules 467 $w = My::Widgets->widget( extra => { msg => 'Hello Badger' } ); 468 469You can also create factory objects: 470 471 my $factory = My::Widgets->new( 472 widget_path => ['His::Widget', 'Her::Widget'], 473 widgets => { 474 extra => 'Another::Widget::Module', 475 super => 'Golly::Gosh', 476 } 477 ); 478 479 $w = $factory->widget( foo => { msg => 'Hello World' } ); 480 481The L<Badger::Factory::Class> module can be used to simplify the process 482of defining factory subclasses. 483 484 package My::Widgets; 485 486 use Badger::Factory::Class 487 item => 'widget', 488 path => 'My::Widget Your::Widget'; 489 widgets => { 490 extra => 'Another::Widget::Module', 491 super => 'Golly::Gosh', 492 }; 493 494=head1 DESCRIPTION 495 496This module implements a base class factory object for loading modules and 497instantiating objects on demand. It originated in the L<Template::Plugins> 498module, evolved over time in various directions for other projects, and was 499eventually pulled back into line to become C<Badger::Factory>. 500 501=head2 Defining a Factory Module 502 503The C<Badger::Factory> module isn't designed to be used by itself. Rather it 504should be used as a base class for your own factory modules. For example, 505suppose you have a project which has lots of C<My::Widget::*> modules. You can 506define a factory for them like so: 507 508 package My::Widgets; 509 use base 'Badger::Factory'; 510 511 our $ITEM = 'widget'; 512 our $ITEMS = 'widgets'; 513 our $WIDGET_PATH = ['My::Widget', 'Your::Widget']; 514 our $WIDGET_DEFAULT = 'foo'; 515 our $WIDGET_NAMES = { 516 html => 'HTML', 517 }; 518 519 # lookup table for any non-standard spellings/capitalisations/paths 520 our $WIDGETS = { 521 url => 'My::Widget::URL', # non-standard capitalisation 522 color => 'My::Widget::Colour', # different spelling 523 amp => 'Nigels::Amplifier', # different path 524 }; 525 526 1; 527 528The C<$ITEM> and C<$ITEMS> package variables are used to define the 529singular and plural names of the items that the factory is responsible for. 530In this particular case, the C<$ITEMS> declaration isn't strictly 531necessary because the module would correctly "guess" the plural name 532C<widgets> from the singular C<widget> defined in C<$ITEM>. However, 533this is only provided as a convenience for those English words that 534pluralise regularly and shouldn't be relied upon to work all the time. 535See the L<pluralise()|Badger::Utils/pluralise()> method in L<Badger::Utils> 536for further information, and explicitly specify the plural in C<$ITEMS> if 537you're in any doubt. 538 539The C<$WIDGET_PATH> is used to define one or more base module names under 540which your widgets are located. The name of this variable is derived 541from the upper case item name in C<$ITEM> with C<_PATH> appended. In this 542example, the factory will look for the C<Foo::Bar> module as either 543C<My::Widget::Foo::Bar> or C<Your::Widget::Foo::Bar>. 544 545The C<$WIDGET_DEFAULT> specifies the default item name to use if a request 546is made for a module using an undefined or false name. If you don't specify 547any value for a default then it uses the literal string C<default>. Adding 548a C<default> entry to your C<$WIDGET_NAMES> or C<$WIDGETS> will have the same 549effect. 550 551The C<$WIDGET_NAMES> is used to define any additional name mappings. This is 552usually required to handle alternate spellings or unusual capitalisations that 553the default name mapping algorithm would get wrong. For example, a request for 554an C<html> widget would look for C<My::Widget::Html> or C<Your::Widget::Html>. 555Adding a C<$WIDGET_MAP> entry mapping C<html> to C<HTML> will instead send it 556looking for C<My::Widget::HTML> or C<Your::Widget::HTML>. 557 558If you've got any widgets that aren't located in one of these locations, 559or if you want to provide some aliases to particular widgets then you can 560define them in the C<$WIDGETS> package variable. The name of this variable 561is the upper case conversion of the value defined in the C<$ITEMS> package 562variable. 563 564=head2 Using Your Factory Module 565 566Now that you've define a factory module you can use it like this. 567 568 use My::Widgets; 569 570 my $widgets = My::Widgets->new; 571 my $foo_bar = $widgets->widget('Foo::Bar'); 572 573The C<widget()> method is provided to load a widget module and instantiate 574a widget object. 575 576The above example is equivalent to: 577 578 use My::Widget::Foo::Bar; 579 my $foo_bar = My::Widget::Foo::Bar->new; 580 581Although it's not I<strictly> equivalent because the factory could just 582has easily have loaded it from C<Your::Widget::Foo::Bar> in the case that 583C<My::Widget::Foo::Bar> doesn't exist. 584 585You can specify additional arguments that will be forwarded to the object 586constructor method. 587 588 my $foo_bar = $widgets->widget('Foo::Bar', x => 10, y => 20); 589 590If you've specified a C<$WIDGET_DEFAULT> for your factory then you can call 591the L<widget()> method without any arguments to get the default object. 592 593 my $widget = $widgets->widget; 594 595You can use the L<default()> method to change the default module. 596 597 $widgets->default('bar'); 598 599The factory module can be customised using configuration parameters. For 600example, you can provide additional values for the C<widget_path>, or define 601additional widgets: 602 603 my $widgets = My::Widgets->new( 604 widget_path => ['His::Widget', 'Her::Widget'], 605 widgets => { 606 extra => 'Another::Widget::Module', 607 super => 'Golly::Gosh', 608 } 609 ); 610 611The factory module is an example of a L<prototype()|Badger::Prototype> module. 612This means that you can call the C<widget()> method as a class method to save 613yourself of explicitly creating a factory object. 614 615 my $widget = My::Widgets->widget('Foo::Bar'); 616 617=head1 METHODS 618 619=head2 new() 620 621Constructor method to create a new factory module. 622 623 my $widgets = My::Widgets->new; 624 625=head2 path($path) 626 627Used to get or set the factory module path. 628 629 my $path = $widgets->path; 630 $widgets->path(['My::Widgets', 'Your::Widgets', 'Our::Widgets']); 631 632Calling the method with arguments replaces any existing list. 633 634=head2 names($names) 635 636Used to get or set the names mapping table. 637 638 my $names = $widgets->names; 639 $widgets->names({ html => 'HTML' }); 640 641Calling the method with arguments replaces any existing names table. 642 643=head2 default($name) 644 645Used to get or set a name for the default item name. The default value is 646the literal string C<default>. This allows you to add a C<default> entry 647to either your L<names()> or L<items()> and it will be located automatically. 648 649=head2 items(%items) 650 651Used to fetch or update the lookup table for mapping names to modules. 652 653 my $items = $widgets->items; 654 $widgets->items( foo => 'My::Plugin::Foo' ); 655 656Calling the method with arguments (named parameters or a hash reference) 657will add the new definitions into the existing table. 658 659This method can also be aliased by the plural name defined in C<$ITEMS> 660in your subclass module. 661 662 $widgets->widgets; 663 664=head2 item($name,@args) 665 666Method to load a module and instantiate an object. 667 668 my $widget = $widgets->item('Foo'); 669 670Any additional arguments provided after the module name are forwarded to the 671object's C<new()> constructor method. 672 673 my $widget = $widgets->item( Foo => 10, 20 ); 674 675This method can also be aliased by the singular name defined in C<$ITEM> 676in your subclass module. 677 678 my $widget = $widgets->widget( Foo => 10, 20 ); 679 680The module name specified can be specified in lower case. The name is 681capitalised as a matter of course. 682 683 # same as Foo 684 my $widget = $widgets->widget( foo => 10, 20 ); 685 686Multi-level names can be separated with dots rather than C<::>. This is in 687keeping with the convention used in the Template Toolkit. Each element after 688a dot is capitalised. 689 690 # same as Foo::Bar 691 my $widget = $widgets->widget( 'foo.bar' => 10, 20 ); 692 693=head1 INTERNAL METHODS 694 695=head2 type_args(@args) 696 697This method can be re-defined by a subclass to perform any pre-manipulation on 698the arguments passed to the L<item()> method. The first argument is usually 699the type (i.e. name) of module requested, followed by any additional arguments 700for the object constructor. 701 702 my ($self, $type, @args) = @_; 703 704The method should return them like so: 705 706 return ($type, @args); 707 708=head2 find($type,\@args) 709 710This method is called to find and dynamically load a module if it doesn't 711already have an entry in the internal C<items> table. It iterates through 712each of the base paths for the factory and calls the L<load()> method to 713see if the module can be found under that prefix. 714 715=head2 load(@module_names) 716 717This method is called to dynamically load a module. It iterates through 718each of the module name passed as arguments until it successfully loads 719one. At that point it returns the module name that was successfully 720loaded and ignores the remaining arguments. If none of the modules can 721be loaded then it returns C<undef> 722 723=head2 found($name,$item,\@args) 724 725This method is called when an item has been found, either in the internal 726C<items> lookup table, or by a call to L<find()>. The L<$item> argument is 727usually a module name that is forwarded onto L<found_module()>. However, it 728can also be a reference which will be forwarded onto one of the following 729methods depending on its type: L<found_array()>, L<found_hash()>, 730L<found_scalar()>, L<found_object()> (and in theory, C<found_regex()>, 731C<found_glob()> and maybe others, but they're not implemented). 732 733The result returned by the appropriate C<found_XXXXX()> method will then 734be forwarded onto the L<result()> method. The method returns the result 735from the L<result()> method. 736 737=head2 found_module($module) 738 739This method is called when a requested item has been mapped to a module name. 740The module is loaded if necessary, then the L<construct()> method is called 741to construct an object. 742 743=head2 found_array(\@array) 744 745An entry in the C<items> (aka C<widgets> in our earlier example) table 746can be a reference to a list containing a module name and a separate class 747name. 748 749 my $widgets = My::Widgets->new( 750 widgets => { 751 wizbang => ['Wiz::Bang', 'Wiz::Bang::Bash'], 752 }, 753 ); 754 755If the C<wizbang> widget is requested from the C<My::Widgets> factory 756in the example above, then the L<found()> method will call C<found_array()>, 757passing the array reference as an argument. 758 759The module listed in the first element is loaded. The class name in 760the second element is then used to instantiate an object. 761 762=head2 found_hash(\%hash) 763 764This method isn't implemented in the base class, but can be defined by 765subclasses to handle the case where a request is mapped to a hash reference. 766 767=head2 found_scalar(\$scalar) 768 769This method isn't implemented in the base class, but can be defined by 770subclasses to handle the case where a request is mapped to a scalar reference. 771 772=head2 found_object($object) 773 774This method isn't defined in the base class, but can be defined by subclasses 775to handle the case where a request is mapped to an existing object. 776 777=head2 construct($name,$class,\@args) 778 779This method instantiates a C<$class> object using the arguments provided. 780In the base class this method simply calls: 781 782 $class->new(@$args); 783 784=head2 result($name,$result,\@args) 785 786This method is called at the end of a successful request after an object 787has been instantiated (or perhaps re-used from an internal cache). In the 788base class it simply returns C<$result> but can be redefined in a subclass 789to do something more interesting. 790 791=head2 module_names($type) 792 793This method performs the necessary mapping from a requested module name to 794its canonical form. 795 796=head2 not_found($name,@args) 797 798This method is called when the requested item is not found. The method simply 799throws an error using the C<not_found> message format. The method can be 800redefined in subclasses to perform additional fallback handing. 801 802=head2 can($method) 803 804This method implements the magic to ensure that the item-specific accessor 805methods (e.g. C<widget()>/C<widgets()>) are generated on demand. 806 807=head2 AUTOLOAD(@args) 808 809This implements the other bit of magic to generate the item-specific accessor 810methods on demand. 811 812=head1 AUTHOR 813 814Andy Wardley L<http://wardley.org/> 815 816=head1 COPYRIGHT 817 818Copyright (C) 2006-2009 Andy Wardley. All Rights Reserved. 819 820This module is free software; you can redistribute it and/or 821modify it under the same terms as Perl itself. 822 823=head1 SEE ALSO 824 825L<Badger::Factory::Class>, L<Badger::Codecs>. 826 827=cut 828 829# Local Variables: 830# mode: perl 831# perl-indent-level: 4 832# indent-tabs-mode: nil 833# End: 834# 835# vim: expandtab shiftwidth=4: 836