"Can't modify non-lvalue subroutine call" furrows my brow

R

rickcasey

I modified a small subroutine in a larger Perl module that we are
attempting to port from a version that uses a commercial database
(Sybase) to an open source one (PostGres). One small modification has
resulted in this error message that I don't understand:
"Can't modify non-lvalue subroutine call at
lib/NHGRI/LDM/TableManager.pm line 1159."

1) does the message mean I cannot modify this subroutine at all?
2) or, hopefully, is there something wrong with my Perl syntax?
(judging from other group messages that also mention this error, I hope
it's the latter.)

TIA,
Rick


Here is what the code looks like around line 1159:

sub getQuotableFieldsHash {
my $self = shift;
my $dbh = $self->{dbc}->connect;
my $table = $self->{table};
my $db_type = $self->getDBD();
my %quotable = ();
my %quoted_types = ();
my $sql;

if ($db_type eq "Sybase") {
%quoted_types = (text => 1, varchar => 1, char => 1, datetime => 1);
$sql = qq!
SELECT c.name as Field,
t.name as Type
FROM sysobjects o, syscolumns c, systypes t
WHERE c.id = o.id
AND t.usertype = c.usertype
AND o.name = '$table'!;

} elsif ($db_type eq "Oracle") {
%quoted_types = (varchar2 => 1, nvarchar2 => 1, long => 1, char => 1,
nchar => 1, date => 1, clob => 1, nclob => 1);
$sql = qq!
SELECT column_name, data_type
FROM all_tab_columns
WHERE table_name = '$table'
!;
} elsif ($db_type eq "Pg") {
# (rc, 20Jan05)
# Here is where the SQL must get all columns in all tables from
PostGres system tables,
# Here, we make use of the convenient system view Columns in
information_schema.
%quoted_types = (varchar2 => 1, nvarchar2 => 1, long => 1, char => 1,
nchar => 1, date => 1, clob => 1, nclob => 1);
$sql = qq!
select column_name, data_type
from information_schema.columns
WHERE table_name = '$table'
!;
}

1159--> $dbh->errstr = $dbh->errstr . $sql;
my $ra_result = $dbh->selectall_arrayref($sql) or croak
$dbh->errstr;

foreach my $ra_row (@{$ra_result}) {
my $dtype = lc($ra_row->[1]);
my $field_name = $ra_row->[0];
$field_name = uc($field_name); #if ($db_type eq "Oracle");
$quotable{$field_name} = 1 if $quoted_types{$dtype};
}


return \%quotable;
 
A

A. Sinan Unur

1159--> $dbh->errstr = $dbh->errstr . $sql;

Compare with the following:

use strict;
use warnings;

sub dontmodify { "I said, don't modify!!!" }

dontmodify = 5;

__END__


Sinan
 
B

Brian McCauley

rickcasey said:
I modified a small subroutine in a larger Perl module that we are
attempting to port from a version that uses a commercial database
(Sybase) to an open source one (PostGres). One small modification has
resulted in this error message that I don't understand:
"Can't modify non-lvalue subroutine call at
lib/NHGRI/LDM/TableManager.pm line 1159."

1) does the message mean I cannot modify this subroutine at all?

What do you mean by "modify" and "this subroutine"?

The DBI method strerr is not non-lvalued. It just returns a value. You
cannot use it on the left of an assignment statement.

This means it is wrong to say

$dbh->errstr = $dbh->errstr . $sql;

Is this the line you changed?

What did it say before you changed it?
 
P

Paul Lalli

rickcasey said:
I modified a small subroutine in a larger Perl module that we are
attempting to port from a version that uses a commercial database
(Sybase) to an open source one (PostGres). One small modification has
resulted in this error message that I don't understand:
"Can't modify non-lvalue subroutine call at
lib/NHGRI/LDM/TableManager.pm line 1159."

1) does the message mean I cannot modify this subroutine at all?
2) or, hopefully, is there something wrong with my Perl syntax?
(judging from other group messages that also mention this error, I hope
it's the latter.)

If you don't know what an error message means, you can always look it up
in
perldoc perldiag

or even have Perl tell you itself, by adding
use diagnostics;
to your code (when developing - not recommended for released code)
Here is what the code looks like around line 1159:

1159--> $dbh->errstr = $dbh->errstr . $sql;

<snip>

So do you see what you've done wrong, when comparing this code to the
explanation of the error message? If not, feel free to post back with
what part of the documentation you're having difficulty understanding.

Paul Lalli
 
A

Anno Siegel

rickcasey said:
I modified a small subroutine in a larger Perl module that we are
attempting to port from a version that uses a commercial database
(Sybase) to an open source one (PostGres). One small modification has

So what *was* the modification? You're hiding info that would help
enormously in telling what is going on.
resulted in this error message that I don't understand:
"Can't modify non-lvalue subroutine call at
lib/NHGRI/LDM/TableManager.pm line 1159."

1) does the message mean I cannot modify this subroutine at all?

It's not modification of the sub that fails (you're not attempting that).
It's assignment to the *call* of a subroutine (a method, in this case),
that doesn't work without additional measures.
2) or, hopefully, is there something wrong with my Perl syntax?
(judging from other group messages that also mention this error, I hope
it's the latter.)

Your syntax is fine. It wouldn't compile otherwise.

[code snipped]
1159--> $dbh->errstr = $dbh->errstr . $sql;

Assigning to a method call is only possible if the method is declared an
"lvalue" routine. That is apparently not the case. I'll assume that
the class of $dbh is not yours, so you can't change that.

Look up the documentation of the ->errstr method and see how to change
an error string. If ->errstr is like many accessor methods,

$dbh->errstr( $dbh->errstr . $sql);

may work, but that's just a guess.

Anno
 
R

rickcasey

Thanks for these replies; most were informative (though replies like
Mr. Unur's are so cryptic they do not help at all). Sorry I failed to
say what exactly I modified; here's what I did:

All I did was to add the elsif branch to the end of the if/else
statement in this subroutine (i.e., the code after
} elsif ($db_type eq "Pg") {

I did not modify how the subroutine is called, or the return statement.


My code does modify what is returned by the subroutine, which is
created in the foreach loop just before the subroutine ends. Now I am
thinking that I need to modify the values in the %quoted_types hash --
because if they are not correct, the %quotable hash will not get
assigned correctly. Could that possibly be the cause of the error?
Thanks, rick
 
A

Anno Siegel

rickcasey said:
Thanks for these replies; most were informative (though replies like
Mr. Unur's are so cryptic they do not help at all). Sorry I failed to
say what exactly I modified; here's what I did:

All I did was to add the elsif branch to the end of the if/else
statement in this subroutine (i.e., the code after
} elsif ($db_type eq "Pg") {

I did not modify how the subroutine is called, or the return statement.

That is hard to swallow. If the *only* change is the one you describe,
the critical line would have been called before and after the change,
and it would have failed for the same reason. Something else must be
going on.

Anno
 
R

rickcasey

You are right; something else was going on.

I was fortunate enough to get a reply from one of the original
programmers of this application, and he said just delete the line
causing the error, i.e. 1159. I did that, and the code worked.

Why Perl was producing that error message is still a mystery, but a
moot point now....

rick
 
A

Anno Siegel

rickcasey said:
You are right; something else was going on.

Please give an attribution and quote some context when replying. This
way nobody knows what you are talking about.
I was fortunate enough to get a reply from one of the original
programmers of this application, and he said just delete the line
causing the error, i.e. 1159. I did that, and the code worked.

Why Perl was producing that error message is still a mystery, but a
moot point now....

No, the reason for the error message is very clear: ->errstr (or what
it's called) is not an lvalue method. The mystery is why the line
was there in the first place, and why it didn't trigger the error
before.

Anno
 
P

Paul Lalli

rickcasey said:
You are right; something else was going on.

I was fortunate enough to get a reply from one of the original
programmers of this application, and he said just delete the line
causing the error, i.e. 1159. I did that, and the code worked.

Why Perl was producing that error message is still a mystery, but a
moot point now....

Did you read *any* of the replies in this thread? How can you call that
a mystery?!

Paul Lalli
 
E

Eric Bohlman

You are right; something else was going on.

I was fortunate enough to get a reply from one of the original
programmers of this application, and he said just delete the line
causing the error, i.e. 1159. I did that, and the code worked.

Sigh. Deleting a line of code simply because it's causing an error
message that you don't understand is voodoo programming. It's like
removing a warning light from your car's dashboard to make it stop coming
on. That programmer gave you some really bad advice.
Why Perl was producing that error message is still a mystery, but a
moot point now....

No, it isn't a mystery. You had:

$dbh->errstr = $dbh->errstr . $sql;

and you got tripped up by the fact that Perl doesn't require parentheses
after a subroutine or method call that doesn't take any arguments. If
that line had been written as:

$dbh->errstr() = $dbh->errstr() . $sql;

it would have been immediately obvious that something fishy was going on.
 
B

bik.mido

Anno said:
Please give an attribution and quote some context when replying. This
way nobody knows what you are talking about.

The problem is with Google: once one could hit "reply" and get a decent
quoting as with a "regular" news client. Now they're changing to the
new inferface (which has some interesting features/advantages but
overall is IMHO less clear and functional) and it doesn't work any
more.

To reply properly one has to (i) switch to Google Groups Beta, (ii) do
(_not_ hit "reply" directly) but select "show options" and then select
"reply" there.


PS: it may be worth to spread the word around people posting from
google who _seem_ to ignore this...


HTH,
Michele (back for a while!)
 
A

Anno Siegel

Tad McClellan said:
I finally gave up waiting for that problem to go away.

Last weekend I added a scorefile entry for postings from google. :-(

It's an archive with a posting facility, not an NNTP server. If it weren't
*Google*, I'd shrug it off.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top