o2bwise has asked for the wisdom of the Perl Monks concerning the following question:


Hi,

I am stuck on a basic package/OOP situation. This is my first time trying to write an OOP package. For this first attempt, I just want a package that performs linear regression.

I have things working up to the place of my inability to resolve a hash data structure. I attempt to do this inside various package functions.

Here is some of the package code:

package regression; use strict; sub new { my ($class) = @_; bless { 'raw_data' => $_[1], 'mean_x' => 0, 'mean_y' => 0, 'slope' => 0, 'y_intercept' => 0 }, $class; } sub get_mean_x { $raw_dataPtr = $_[0]{'raw_data'}; my $counter = 1; my $x_total = 0; print "raw_datePtr: $raw_datePtr\n"; foreach $x (keys %$raw_dataPtr) { ++$counter; $x_total += $x; } my $mean_x = ($x_total/$counter); $self->{'mean_x'} = $mean_x; return ($self->{'mean_x'}); }


The part of the code that is killing me is the following line:

$raw_dataPtr = $_[0]{‘raw_data’}

The following are other syntax attempts:

$raw_dataPtr = $$_[0]{‘raw_data’}

$raw_dataPtr = $self->{‘raw_data’}



The only thing I know is that on this one point, I don’t know what the hell I am doing. I need to resolve the pointer to the hash so that my little package can go about calculating the linear regression related stuff.

Oh, here is the code that is referencing the package:

#!/usr/bin/perl -w use strict; require ('/opt/eHealth/web/aview/perl/site/lib/regression.pm'); open (TEST,">testing.txt"); my ($mean_x,$mean_y,$slope,$y_intercept); my %raw_data = ( 1 => 100, 2 => 160, 2.5 => 182, 3 => 225 ); my $regr = regression->new(\%raw_data); $mean_x = $regr->get_mean_x; #$mean_y = $regr->get_mean_y; #$slope = $regr->get_slope; #$y_intercept = $regr->get_slope; print TEST "Mean_x: $mean_x\tMean_y: $mean_y\tSlope: $slope\t: y inter +cept: $y_intercept\n"; close (TEST);


Can someone show me how to resolve the hash of x,y data points that the package needs to work with? By the way, I have verified that my test code “sees” the package.

Thanks in advance,

Tony

Replies are listed 'Best First'.
Re: basic OOP question
by lostjimmy (Chaplain) on Nov 13, 2008 at 21:02 UTC
    There are a few things you will want to change with this code.
    • Using @_ directly is ugly and hard to decipher, in my opinion. Consider assigning the parameters to a list of variables like so: my ($class, $rawData) = @_ instead of using $_[1].
    • There is no implicit $self in methods like there are in other languages. $self is the first argument passed to the method. You will often see a my $self = shift as the first line in a method.
    • You're missing a few my declarations and there are some typos, so your example doesn't compile.
    Overall the code you need is there. With a few tweaks you should end up with something working like this:
    use strict; package regression; sub new { my ($class, $raw) = @_; bless { 'raw_data' => $raw, 'mean_x' => 0, 'mean_y' => 0, 'slope' => 0, 'y_intercept' => 0 }, $class; } sub get_mean_x { my $self = shift; my $raw_dataPtr = $self->{'raw_data'}; my $counter = 1; my $x_total = 0; for my $x (keys %$raw_dataPtr) { ++$counter; $x_total += $x; } $self->{'mean_x'} = $x_total / $counter; } package main; my ($mean_x,$mean_y,$slope,$y_intercept); my %raw_data = ( 1 => 100, 2 => 160, 2.5 => 182, 3 => 225 ); my $regr = regression->new(\%raw_data); $mean_x = $regr->get_mean_x; print "Mean_x: $mean_x\n";
Re: basic OOP question
by ig (Vicar) on Nov 13, 2008 at 21:11 UTC

    It would probably help you to work through the examples in perlboot, with attention to the section Invoking an instance method.

    When you call your method using $regr->get_mean_x, the instance is provided as an argument. Your method function can use this to access instance variables.

    sub get_mean_x { my $self = shift; my $raw_dataPtr = $self->{raw_data}; my $counter = 1; my $x_total = 0; print "raw_datePtr: $raw_dataPtr\n"; foreach my $x (keys %$raw_dataPtr) { ++$counter; $x_total += $x; } my $mean_x = ($x_total/$counter); $self->{'mean_x'} = $mean_x; return ($self->{'mean_x'}); }
Re: basic OOP question
by Anonymous Monk on Nov 13, 2008 at 21:05 UTC
    I'm all set. I figured it out.

    In one place, my variable was $rawDataPtr and in the other, it was $rawDatePtr.

    Unbelievable!
Re: basic OOP question
by fmerges (Chaplain) on Nov 14, 2008 at 05:21 UTC

    Hi,

    I can only recommed you getting a good perl book or read the documents available here.

    Why you add a code snippet, saying that you wrote it with 'strict' mode, when this is not true? If you look at your code, it doesn't even compile.

    Regards,

    fmerges at irc.freenode.net