[tpm] Is it possible to get a $coderef to an object method?

Scott Elcomb psema4 at gmail.com
Fri Oct 5 13:43:20 PDT 2007


Hi all,

I'd like to create a very lightweight MVC architecture using plugins.
I'm not sure if I'm barking up the right tree with this, but aside
from one issue it seems the idea should be doable.

I've looked at Maypole and Catalyst, but they have far too many
dependencies for my clients' tastes.  What I'm trying to do with the
"mvcplugs" POC is dead simple: drop a plugin object (containing a
combination of model/view/controller methods) into the plugin
directory ("MVCPlugs") and have it automatically load/register when
the main script ("mvcplugs.pl") runs.

Currently this doesn't do much beyond loading/registering an explicit
list of plugins.  The problem shows up when I try to register the
model/view/controller method coderefs in %registry.  In the output
sample (bottom of post) the coderefs showup as "DUMMY" subs.

Is there a way to get valid coderefs or am I headed in the wrong direction?

Thanks in advance,
- Scott.


#// START OF mvcplugs.pl //#
#!/usr/bin/perl

use strict;
use Data::Dumper;

###################################################
# CONFIG (Should read in from file or CLI args)
#
my @plugins = qw[Core PluginTemplate TestPlugin];
my $verbose = 1;
###################################################

my %registry = (
                 'plugins' => {},
                 'models' => {},
                 'views' => {},
                 'controllers' => {}
               );

foreach my $n (@plugins) {
  my $instantiatePlugin = "use MVCPlugs::$n; return MVCPlugs::$n" . '->new()';
  my $plugin = eval($instantiatePlugin);
  my $name = $plugin->name($n);

  %registry->{'plugins'}->{$name} = $plugin;

  if ($verbose) {
    print "[mvcplugs.pl] Plugin Instantiation String: $instantiatePlugin\n";
    print "[mvcplugs.pl] Plugin Instantiaion: $plugin\n";
  }

  if ( %registry->{'plugins'}->{$name}->initPlugin(\%registry) ) {
    print qq[Plugin $name initialized.\n];
  } else {
    print qq[Plugin $name initialization failed!\n];
  }

}

if ($verbose) {
  print "\n[mvcplugs.pl] Dumping Registry:\n" . Dumper(%registry) . "\n\n";
}
#// END OF mvcplugs.pl //#



#// START OF MVCPlugs/TestPlugin.pm //#
package MVCPlugs::TestPlugin;
use strict;
no strict 'refs';
use Data::Dumper;

sub new {
  my $self = {};
  $self->{'NAME'} = 'TEST_PLUGIN';
  bless($self);
  return $self;
}

sub name {
  my $self = shift;
  if (@_) { $self->{'NAME'} = shift }
  return $self->{'NAME'};
}

sub registry {
  my $self = shift;
  if (@_) { $self->{'REGISTRY'} = shift }
  return $self->{'REGISTRY'};
}

sub initPlugin {
  my $self = shift;
  my $registryref = shift;

  ######################
  # This block and the associated "coderefTest" methods are the only
  # differences from the Core.pm & PluginTemplate.pm sample plugins
  #
  # register a model, view, and controller
  $registryref->{'models'}->{'TestModel'} = \&coderefTest1;
  $registryref->{'views'}->{'TestView'} = sub { my $self = shift;
$self->coderefTest2(); };
  $registryref->{'controllers'}->{'TestController'} = \&coderefTest3;
  ######################

  return 1;
}

sub coderefTest1 {
  my $self = shift;
  return 'coderefTest1: call success!';
}

sub coderefTest2 {
  my $self = shift;
  return 'coderefTest2: call success!';
}

sub coderefTest3 {
  my $self = shift;
  return 'coderefTest3: call success!';
}

1;
#// END OF MVCPlugs/TestPlugin.pm //#


#// START OF Sample Output (VERBOSE=1)//#
[mvcplugs.pl] Plugin Instantiation String: use MVCPlugs::Core; return
MVCPlugs::Core->new()
[mvcplugs.pl] Plugin Instantiaion: MVCPlugs::Core=HASH(0x81d77e0)
Plugin Core initialized.
[mvcplugs.pl] Plugin Instantiation String: use
MVCPlugs::PluginTemplate; return MVCPlugs::PluginTemplate->new()
[mvcplugs.pl] Plugin Instantiaion: MVCPlugs::PluginTemplate=HASH(0x81d77f8)
Plugin PluginTemplate initialized.
[mvcplugs.pl] Plugin Instantiation String: use MVCPlugs::TestPlugin;
return MVCPlugs::TestPlugin->new()
[mvcplugs.pl] Plugin Instantiaion: MVCPlugs::TestPlugin=HASH(0x81d7810)
Plugin TestPlugin initialized.

[mvcplugs.pl] Dumping Registry:
$VAR1 = 'models';
$VAR2 = {
          'TestModel' => sub { "DUMMY" }
        };
$VAR3 = 'controllers';
$VAR4 = {
          'TestController' => sub { "DUMMY" }
        };
$VAR5 = 'views';
$VAR6 = {
          'TestView' => sub { "DUMMY" }
        };
$VAR7 = 'plugins';
$VAR8 = {
          'PluginTemplate' => bless( {
                                       'NAME' => 'PluginTemplate'
                                     }, 'MVCPlugs::PluginTemplate' ),
          'TestPlugin' => bless( {
                                   'NAME' => 'TestPlugin'
                                 }, 'MVCPlugs::TestPlugin' ),
          'Core' => bless( {
                             'NAME' => 'Core'
                           }, 'MVCPlugs::Core' )
        };


-- 
  Scott Elcomb
  http://www.psema4.com/


More information about the toronto-pm mailing list