Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

OO Design Question

by Sixtease (Friar)
on Mar 13, 2008 at 07:37 UTC ( #673919=perlquestion: print w/ replies, xml ) Need Help??
Sixtease has asked for the wisdom of the Perl Monks concerning the following question:

Dear fellows,

I'm making a computational-linguistic application (finding clauses in sentences). The whole thing is a perl module and it has a "train_model" function, which will accept training data and train and save a model. The model itself is pluggable. It's a class, the name of which is in a configuration file or provided to the "new" method. The training itself is then delegated to the model class by calling its train method.

However, the model may need to peek at the various configuration I have stored in the main object. So, when calling the model's train method, I would like its first parameter to be actually the main object. The model class is not instantiated (it needn't even provide a "mew" method - just "train" and "tag") and I only have the name of the class.

I could either make the object think he's an instance of the model class (by blessing its copy or setting local @ISA) or I could explicitly call the train function by no strict 'refs'; &"$model_class::train"($self, training_data) or make a change to the overall design.

What do you think?

A skeleton of the layout:

directory content:

MainApp.pm MyModel.pm config

config:

model:MyModel option:Value

MyModel.pm:

sub train { my ($himself, $training_data) = @_; my $option = $himself->{'option'}; ... }

in MainApp.pm:

sub new { my ($class, $conf_file) = @_ my $options = read_conf($conf_file); # now $options == {model=>'MyModel',option=>'Value'} eval "require $options->{model}"; return bless $options, $class; } sub train_model { my ($self, $raw_data) = @_; my $data = do_magic_with($raw_data); #Either: no strict 'refs'; &"$self->{model}::train"($self, $data); #Or: my $model = $self; bless $model, $self->{'model'}; $model->train($data); #Or: { local @ISA = $self->{model}; $self->train($data); } }
use strict; use warnings; print "Just Another Perl Hacker\n";

Comment on OO Design Question
Select or Download Code
Re: OO Design Question
by Sixtease (Friar) on Mar 13, 2008 at 07:42 UTC

    Heh, as usual, formulating the question made me reveal an answer. I'll require the models to provide a "new" method, and say

    my $model = $self->{'model'}->new($self); $model->train($data);

    Other suggestions are of course most welcome!

    use strict; use warnings; print "Just Another Perl Hacker\n";
      I see a red herring my $model = $self->{'model'}->new($self);
Re: OO Design Question
by plobsing (Friar) on Mar 14, 2008 at 06:00 UTC
    In stead of holding onto the model name, you could hold on to the resources that the model gives you. In this case (simplification?) its just one sub that you keep around and dispatch to.
    new { my ($class, $conf_file) = @_; my $opts = read_conf( $conf_file ); $opts->{model_trainer} = eval sprintf q{ require %s; \&%s::train }, ($opts->{model}) x 2; # ... validation ... bless $opts, $class; } sub train { my $self = shift; my $data = voodoo( shift ); $self->{model_trainer}->( $self, $data ); }
    I don't really like using eval much. There's probably a better way to get a hard ref to the train function, but I don't see it right now.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://673919]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (12)
As of 2014-07-25 21:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (175 votes), past polls