Gossamer Forum
Home : General : Perl Programming :

Object Orientated woes

Quote Reply
Object Orientated woes
Hi

I've just finished writing a rather big module containing a lot of SQL tricks to save me some time. I'm now trying to tie this into my programs, however I'm a little consufed by this OO business.

From other modules I've seen I think I need to create a 'new' sub routine so I can call my module with something like:

Code:
use WS::MySQL;
my $mysql = WS::MySQL->new();

The only problem is, I don't know what should go in new. I've read and heard about blessing this and belssing that but I'm still a little confused. Anyone fancy telling me what I need to put in there? At the moment, I've just got this:

Code:
sub new {

my $class = shift;
return bless {}, $class;
}

But surely I need more than that?!

- wil
Quote Reply
Re: [Wil] Object Orientated woes In reply to
It depends what options you want.

You need to return a reference so in its basic format it would be:

Code:
sub new {
my $self = shift;
return bless {}, $self;
}

That means in your script you can do my $obj = new Module; and then you can access your method's like $obj->method

If you need more flexibility you can do something like:

Code:
sub new {
my $class = shift;
my $self = {};
$self = { A => 'B', C => 'D' };

return bless $self, $class;

}

Then in your main script you can set or use those values, eg for my template parser I have a "set" key which holds the name of the template set I want to use and so in the main script I can access this value with:

$obj->{set}

...or I can change the value with $obj->{set} = 'foo';

So basically it just depends what you need.

Last edited by:

RedRum: Feb 5, 2002, 7:28 AM
Quote Reply
Re: [RedRum] Object Orientated woes In reply to
Hm, when I try and do that, using something like this:

Code:
use WS::MySQL;
my $mysql = WS::MySQL->new();

my $tbl_info = $mysql->get($dbh,"ata_members");

Code:
Can't locate object method "members" via package "WS::MySQL=HASH(0x826e650)" at index.cgi line 217.

But when I use

Code:
my $tbl_info = WS::MySQL->get($dbh,"ata_members");

all is well, and I get no error. :-\

- wil
Quote Reply
Re: [Wil] Object Orientated woes In reply to
Which new sub?....the basic one?

That error means you are missing a members() routine in WS::MySQL
Quote Reply
Re: [RedRum] Object Orientated woes In reply to
No, the sub is there. I think to bless soemthing ?Blush

- wil
Quote Reply
Re: [Wil] Object Orientated woes In reply to
What is on line 127?

You are using $mysql->get() so why is it looking for members() ?
Quote Reply
Re: [RedRum] Object Orientated woes In reply to
my $tbl_info = WS::MySQL->get($dbh,"ata_members");
my @data = $tbl_info->members("type");


I want to replace WS::MySQL in the above with $mysql->

I tried doing this by adding this line at the top:

use WS::MySQL;
my $mysql = WS::MySQL->new();


And then adding this to my WS::MySQL module:

sub new {

my $self = shift;
return bless {}, $self;
}


- wil
Quote Reply
Re: [Wil] Object Orientated woes In reply to
It should work fine although you should use

new WS::MySQL

and not

WS::MySQL->new()
Quote Reply
Re: [RedRum] Object Orientated woes In reply to
Still doesn't want to work. Thanks for trying, though.

- wil
Post deleted by RedRum In reply to

Last edited by:

RedRum: Feb 6, 2002, 3:04 AM
Quote Reply
Re: [Wil] Object Orientated woes In reply to
Heres a quick example...pehaps you can pick it apart and get it to work in your script...

Module:

Code:
package Foo;

sub new { return bless{}, shift }

sub test { ref shift }

'Foo'

Script:

Code:
#!/usr/bin/perl

use Foo;

print "Content-type: text/html\n\n";

my $obj = new Foo;

print $obj->test;

Last edited by:

RedRum: Feb 6, 2002, 3:05 AM
Quote Reply
Re: [RedRum] Object Orientated woes In reply to
Hm, still can't get it to work. Here's relevant snippets from my programs, maybe you can spot what I'm doing wrong.

Code:
package WS::MySQL;
# ------------------------------------------------------------------------

use strict;
use DBI;
use vars qw/$VERSION/; # to be replaced by our in perl 5.6

$VERSION = 1.00;

sub get {
# ------------------------------------------------------------------------
# Issues a SHOW COLUMNS query, and returns a reference to an
# object that contains the information returned by the query
# about the table's columns.
#

my ($class, $dbh, $tbl_name) = @_;

# hash ref containing table information
my $self = {};

# save table name
$self->{table} = $tbl_name;

$self->{data} = $dbh->selectall_arrayref ("SHOW COLUMNS FROM $tbl_name")
or die ("No information found for $tbl_name\n");

# construct a row map that associates each column name with the
# row of SHOW COLUMNS output for that column, to make it easier
# to find information by column name later

$self->{row} = {};
foreach my $row_ref (@{$self->{data}})
{
$self->{row}->{$row_ref->[0]} = $row_ref;
}

# bless object into class, return reference to it.
return (bless ($self, $class));

}

sub members {
# ------------------------------------------------------------------------
# This function returns a list of legal column members.
#

my ($self, $col_name) = @_;
my @val;

@val = $self->_column_info ($col_name);

# strip "enum(" or "set(" from beginning and ")" from end
# of "type" value
$val[1] =~ s/^[^(]*\((.*)\)$/$1/;

# split on commas, then trim quotes from the end of each word.
@val = split (/,/, $val[1]);
s/^'(.*)'$/$1/ foreach (@val);

return (@val);

}

sub new {
# ------------------------------------------------------------------------
#

my $class = shift;
my $self = { @_ };
bless $self, $class;

}

1;

And in my script, I have:

Code:
use WS::MySQL;
my $mysql = WS::MySQL->new();

$dbh = $mysql->connect; # works ok

my $tbl_info = WS::MySQL->get($dbh,"ata_members"); # works ok
my @data = $tbl_info->members("type");

my $tbl_info = $mysql->get($dbh,"ata_members"); # does not work - line 217.
my @data = $tbl_info->members("type");

Thanks.

- wil

Last edited by:

Wil: Feb 6, 2002, 3:43 AM
Quote Reply
Re: [Wil] Object Orientated woes In reply to
Oh, and the error message I get when it dies is:

Code:
Can't locate object method "members" via package "WS::MySQL=HASH(0x82710d0)" at index.cgi line 217.

I've edited my above post to highlight line 217.

- wil
Quote Reply
Re: [Wil] Object Orientated woes In reply to
>>
my $tbl_info = $mysql->get($dbh,"ata_members"); # does not work - line 217. my @data = $tbl_info->members("type");
<<

I think line 217 is the one below the one you've indicated and the part causing the error is:

my @data = $tbl_info->members("type");

Why are you blessing in get() ?....that is the cause of the problem.

All you'd need to do is grab the table info from $obj->get() as a hashref for example:

return $self; # Not return (bless ($self, $class));

So...

my $info = $mysql->get($dbh, "ata_members");

....instead of creating another object and then you can just do:

my @data = $mysql->members("type");

There's no reason to create a second object.

Then you can do whatever you want with $info. You can access individual keys with:

my $key = $mysql->get($dbh, "ata_members")->{some_key};

Last edited by:

RedRum: Feb 6, 2002, 4:14 AM
Quote Reply
Re: [RedRum] Object Orientated woes In reply to
Hm, but I must have a reference to $tbl_info?

- wil