Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Readonly error on $_ again (better format, mehopes)

by jeroenes (Priest)
on Jan 05, 2001 at 16:10 UTC ( [id://50037]=perlquestion: print w/replies, xml ) Need Help??

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

Note: My previous posting looks terrible, but I can't update it... so I reposted. If someone could remove the ugly one, please do so.

I encountered something that puzzles me. I have a workaround, but I'd like to know why it happens. If you would be so kind to share your wisdom with me, or at least point me to some docs, I'd be very grateful. It's my very first OOP project in perl, so please be patient with me.

In short, a function that does a SWITCH:{$_ = .... gets an error 'Modification of a read-only value attempted' when when two function calls back a $_ was passed as the first parameter. It's getting lengthy here, so....

Let's start with the last function. After two hard-to-debug errors, I decided to write a module that checks whether a method was called with a $self->. This module is exports the function selfcontrol and contains the following code:

package Selfcontrol; use strict; use Exporter; use vars qw( @EXPORT @ISA @VERSION); @VERSION = 0.01; @ISA = qw( Exporter ); @EXPORT = qw( &selfcontrol); use Carp; sub selfcontrol{ my $self = shift; my $ref = ref( $self); SWITCH: { $_ = $ref; last unless $_; last if /REF/; last if /SCALAR/; last if /ARRAY/; last if /HASH/; last if /CODE/; last if /GLOB/; return $self; } confess 'You forget the $self->, you idiot!'. "\n\tInstead you gave me $self that refs to '$ref'"; }
Normally, this works. I call this function in the first line of a method this way:
my $self = $bugfree ? shift : selfcontrol( shift );
because I fear the selfcontrol will slow things up when it's called too often, and I have a feeling that using modules to find out the caller would not greatly improve on speed. $bugfree is a global scalar declared with use vars.

Well, somewhere in my actual class (well, at line 300 of over 1100) I use a for loop:

for ('Operator', 'SQLStatement', 'PerlVariable', 'CompModifier +') { $self->findTokenPos( $_, $i, $blocklast ); $numberOthers += scalar( @_ ); }
The findTokenPos first does the selfcontrol magic, and it gets beaten like hell:
# # Modification of a read-only value attempted, chunk 1. File ':Selfcontrol.pm'; Line 15 # Selfcontrol::selfcontrol('embedSQL=HASH(0x2b31864)') called File ':embedSQL.pm'; Line 876 # embedSQL::findTokenPos('embedSQL=HASH(0x2b31864)', 'Operator', 2 +, 3) called File ':embedSQL.pm'; Line 292 # embedSQL::synonymsSELECT('embedSQL=HASH(0x2b31864)') called File ':embedSQL.pm'; Line 202 # embedSQL::parse('embedSQL=HASH(0x2b31864)') called File 'Documenten:embedSQL:test1.pl'; Line 10
This is my workaround:
for my $str ('Operator', 'SQLStatement', 'PerlVariable', 'Comp +Modifier') { $self->findTokenPos( $str, $i, $blocklast ); $numberOthers += scalar( @_ ); }
And hey, no errors any more! Could anyone please telling me why the first for loop doesn't work? Thanks a lot!

Jeroen

Replies are listed 'Best First'.
Re: Readonly error on $_ again (better format, mehopes)
by repson (Chaplain) on Jan 05, 2001 at 16:38 UTC
    I just viewed the html source and everything looked fine there, try wrapping the whole thing with code tags maybe?

    The problem it that in selfcontrol you assign to $_. In the for loop in your calling code $_ has been aliased to 'Operator' and you are trying to assign to that. In effect you are trying to do 'Operator' = 'foo'; which is not allowed.

    The actual problem is that $_ is by default global between all subs in all packages (a topic which has been discussed on this site several times). The solution: start subs where you use $_ with local $_; or avoid $_ in non innermost loops (like your workaround did) or in this case use a different switch method such as:

    for ($ref) { last unless $_; last if /REF/; return $self; }
    Which works because for loops automatically localize $_.
    I don't feel like saying more but you might want to look for the nodes which complain about $_, I remember there being at least 2.
      Aha, I see.

      I had assumed that $_ get's local in any sub. I can see the picture, thanx everyone!

      Jeroen
      I was dreaming of guitarnotes that would irritate an executive kind of guy (FZ)

Re: Readonly error on $_ again (better format, mehopes)
by ChOas (Curate) on Jan 05, 2001 at 16:26 UTC
    jeroenes posted the formatted question on his homenode

    GreetZ!,
      ChOas

    print "profeth still\n" if /bird|devil/;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://50037]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-03-28 10:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found