From: Justin C on

I'm using Spreadsheet::WriteExcel, and (I think) I've created a
reference to the worksheet. When I try to use this elsewhere I get:
Can't call method ... on unblessed reference at ...

This is the minumum I've been able to cut the code down to (sorry it's
not shorter). The problem line is 26. As per the Spreadsheet::WriteExcel
documentation I've created the object, and it's a reference to that
object that I've passed from a subroutine to Main:: to pass on to other
subroutines.

I'm slowly getting to grips with references, I seem to be OK (mostly)
with scalar, array, and harh refs, but what is this? An object
reference? I'm working on it but I haven't got it yet. Anyway, here's
the code.

#!/usr/bin/perl

use warnings;
use strict;
use Spreadsheet::WriteExcel;

my ($worksheet, $format) = create_excel_file();

artist_chart() ;

sub artist_chart {
my ($position, $last_month, $artist) = ('7', '4', 'Banksy');
populate_spreadsheet(0, $position, $last_month, $artist);
}
sub create_excel_file {
my $fname = "/var/local/chart/boris.xls";
my $workbook = Spreadsheet::WriteExcel->new($fname);
my $ws = $workbook->add_worksheet();
my $format = set_sheet_table_borders($workbook);
return (\$ws, \$format);
}
sub populate_spreadsheet {
my $start_col = shift;
my $items = \@_;
my $row = $_[0] + 1;
$worksheet->write_row($row,$start_col,$items,$format);
}
sub set_sheet_table_borders {
my $wb = shift;
my $format = $wb->add_format(
border => 7,
);
return $format;
}

__END__


Thank you for any help you can give with this.

Justin.

--
Justin C, by the sea.
From: DouglasG.Wilson on
On Dec 8, 10:45 am, Justin C <justin.0...(a)purestblue.com> wrote:
> I'm using Spreadsheet::WriteExcel, and (I think) I've created a
> reference to the worksheet. When I try to use this elsewhere I get:
> Can't call method ... on unblessed reference at ...
>
> This is the minumum I've been able to cut the code down to (sorry it's
> not shorter). The problem line is 26. As per the Spreadsheet::WriteExcel
> documentation I've created the object, and it's a reference to that
> object that I've passed from a subroutine to Main:: to pass on to other
> subroutines.
>
> I'm slowly getting to grips with references, I seem to be OK (mostly)
> with scalar, array, and harh refs, but what is this? An object
> reference? I'm working on it but I haven't got it yet. Anyway, here's
> the code.
>
>
> my ($worksheet, $format) = create_excel_file();

You're returning references to the worksheet and format objects here:
>     return (\$ws, \$format);}
Just return the objects:
return ($ws, $format);}

Then this should work:
>     $worksheet->write_row($row,$start_col,$items,$format);}

HTH,
- Douglas Wilson
From: Ben Morrow on

Quoth Justin C <justin.0911(a)purestblue.com>:
>
> I'm using Spreadsheet::WriteExcel, and (I think) I've created a
> reference to the worksheet. When I try to use this elsewhere I get:
> Can't call method ... on unblessed reference at ...
>
> This is the minumum I've been able to cut the code down to (sorry it's
> not shorter). The problem line is 26. As per the Spreadsheet::WriteExcel
> documentation I've created the object, and it's a reference to that
> object that I've passed from a subroutine to Main:: to pass on to other
> subroutines.

An object is already a reference. You don't need to take another layer
of reference, just return the object.

> I'm slowly getting to grips with references, I seem to be OK (mostly)
> with scalar, array, and harh refs, but what is this? An object
> reference? I'm working on it but I haven't got it yet. Anyway, here's
> the code.
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use Spreadsheet::WriteExcel;
>
> my ($worksheet, $format) = create_excel_file();
>
> artist_chart() ;

Don't pass parameters to subs through globals. It's very confusing.

artist_chart($worksheet, $format);

> sub artist_chart {

(Add the parameters here, and pass them to populate_spreadsheet, of
course.)

> my ($position, $last_month, $artist) = ('7', '4', 'Banksy');
> populate_spreadsheet(0, $position, $last_month, $artist);
> }
> sub create_excel_file {
> my $fname = "/var/local/chart/boris.xls";
> my $workbook = Spreadsheet::WriteExcel->new($fname);
> my $ws = $workbook->add_worksheet();
> my $format = set_sheet_table_borders($workbook);
> return (\$ws, \$format);

Just leave off the '\'s here.

return ($ws, $format);

Ben

From: Jens Thoms Toerring on
Justin C <justin.0911(a)purestblue.com> wrote:

> I'm using Spreadsheet::WriteExcel, and (I think) I've created a
> reference to the worksheet. When I try to use this elsewhere I get:
> Can't call method ... on unblessed reference at ...

> This is the minumum I've been able to cut the code down to (sorry it's
> not shorter). The problem line is 26. As per the Spreadsheet::WriteExcel
> documentation I've created the object,

You asked for an object to be created and what you get back is
already a reference - objects are references, just, due to being
bless'ed, with some extra magic attached (and you shouldn't need
to care what that reference points to, that's what objects are
all about). Thus you add one unnecessary level of indirection
when you return a reference to what you got from the functions
that created the objects.

> and it's a reference to that
> object that I've passed from a subroutine to Main:: to pass on to other
> subroutines.

And that's not the right thing to do, in the routine the reference
to the object gets passed to you need the object (a blessed refe-
rence) itself.

> I'm slowly getting to grips with references, I seem to be OK (mostly)
> with scalar, array, and harh refs, but what is this? An object
> reference? I'm working on it but I haven't got it yet. Anyway, here's
> the code.

> #!/usr/bin/perl

> use warnings;
> use strict;
> use Spreadsheet::WriteExcel;

> my ($worksheet, $format) = create_excel_file();

> artist_chart() ;

> sub artist_chart {
> my ($position, $last_month, $artist) = ('7', '4', 'Banksy');
> populate_spreadsheet(0, $position, $last_month, $artist);
> }
> sub create_excel_file {
> my $fname = "/var/local/chart/boris.xls";
> my $workbook = Spreadsheet::WriteExcel->new($fname);

First object created.

> my $ws = $workbook->add_worksheet();

And a "worksheet" object.

> my $format = set_sheet_table_borders($workbook);

And here you create a "format" object.

> return (\$ws, \$format);

And here you pass back references to two to of the objects which
already are references. That's verkill and it doesn't look as if
it is what you really want to do. Leave it at

return ( $ws, $format );
> }

and you rather likely will be fine, especially since the
way you use them looks very much as if you need the object
itself and not a reference to it. I.e. when you later do

> sub populate_spreadsheet {
> my $start_col = shift;
> my $items = \@_;
> my $row = $_[0] + 1;
> $worksheet->write_row($row,$start_col,$items,$format);
> }

you need a "worksheet" object and not a reference to such
an object - or you would need to dereference $worksheet at
this place to get back the object itself.

> sub set_sheet_table_borders {
> my $wb = shift;
> my $format = $wb->add_format(
> border => 7,
> );
> return $format;
> }
Regards, Jens
--
\ Jens Thoms Toerring ___ jt(a)toerring.de
\__________________________ http://toerring.de
From: sln on
On Tue, 08 Dec 2009 18:45:19 -0000, Justin C <justin.0911(a)purestblue.com> wrote:

>
>I'm using Spreadsheet::WriteExcel, and (I think) I've created a
>reference to the worksheet. When I try to use this elsewhere I get:
>Can't call method ... on unblessed reference at ...
>
>This is the minumum I've been able to cut the code down to (sorry it's
>not shorter). The problem line is 26. As per the Spreadsheet::WriteExcel
>documentation I've created the object, and it's a reference to that
>object that I've passed from a subroutine to Main:: to pass on to other
>subroutines.
>
>I'm slowly getting to grips with references, I seem to be OK (mostly)
>with scalar, array, and harh refs, but what is this? An object
>reference? I'm working on it but I haven't got it yet. Anyway, here's
>the code.
>
>#!/usr/bin/perl
>
>use warnings;
>use strict;
>use Spreadsheet::WriteExcel;
>
>my ($worksheet, $format) = create_excel_file();
^^^^^^^^^^^^^^^^^^^
Never worked with this module, just guessing.
You return reference's (\$ws, \$format).
$workbook->add_worksheet(); and
$wb->add_format(), return references, then you
are returning references to references.
When you dereference by adding the '->' arrow,
$worksheet->'something', it is looking for a method
of a class, an array, hash, ... not another reference.

What happened to $workbook? Don't need it anymore?
Its never stored. Unless of course $workbook->add_worksheet();
creates worksheet object as a wrapper and stores itself ($self)
in a variable of the worksheet object. But that seems unlikely.

>
>artist_chart() ;
>
>sub artist_chart {
> my ($position, $last_month, $artist) = ('7', '4', 'Banksy');
> populate_spreadsheet(0, $position, $last_month, $artist);
>}
>sub create_excel_file {
> my $fname = "/var/local/chart/boris.xls";
> my $workbook = Spreadsheet::WriteExcel->new($fname);
> my $ws = $workbook->add_worksheet();
> my $format = set_sheet_table_borders($workbook);
^^^^^^^^^
Goes away, lost forever!

> return (\$ws, \$format);
>}
>sub populate_spreadsheet {
> my $start_col = shift;
> my $items = \@_;
> my $row = $_[0] + 1;
> $worksheet->write_row($row,$start_col,$items,$format);
^^^^^^
@_ appears to be singularly scoped to each function, so this
cannot be itterated. Its no big deal, but generally, create
an independent (new) array reference everytime this gets
called .. my $items = [@_];

Also, I'm sure you are aware that when items is assigned, @_
contains ($position, $last_month, $artist).

>}
>sub set_sheet_table_borders {
> my $wb = shift;
^^
Here you pass in workbook object, then later it is discarded.
In the function populate_spreadsheet(),
you use the global variables ($worksheet, $format).
This does not have general portability and its hard to tell
where/what these variables are.
I would try to consistently generalize helper functions without
the use/need of globals.

If you have groups of global variables specific to each other,
as some result of making multiple objects, maybe you could store
them in an array of hashs'.

-sln