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:{$_ = .... get's 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
I was dreaming of guitarnotes that would irritate an executive kind of guy (FZ)


In reply to Readonly error on $_ by jeroenes

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.