Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

OO Design Question

by Sixtease (Friar)
on Mar 13, 2008 at 07:37 UTC ( [id://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";

Replies are listed 'Best First'.
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
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others about the Monastery: (4)
As of 2024-04-19 22:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found