Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Modification of a read-only value attempted 2

Status
Not open for further replies.

whn

Programmer
Oct 14, 2007
265
0
0
US
I wrote a small piece of codes to test out ReadOnly.pm.

Code:
use Readonly;

Readonly::Hash my %readOnlyHash1 => (
  'key11'=>{
    'key21'=>1,
    'key22'=>1,
  },
  'xyz'=>{
    'abc'=>1,
  },
);

Readonly::Hash my %readOnlyHash2 => (
  'xyz'=>{
    'abc'=>1,
  },
);

my $k1 = 'key11';
my $k2 = 'key31';
if(defined($readOnlyHash1{$k1}{$k2})) { [b]# line 24[/b]
  print "Defined: Key 1 - $k1, Key 2 - $k2\n";
}
else {
  print "Not Defined: Key 1 - $k1, Key 2 - $k2\n";
}

if(defined($readOnlyHash2{$k1}{$k2})) { [b]# line 31[/b]
  print "Defined: Key 1 - $k1, Key 2 - $k2\n";
}
else {
  print "Not Defined: Key 1 - $k1, Key 2 - $k2\n";
}

And below is the output:
Code:
% test.pl
Not Defined: Key 1 - key11, Key 2 - key31
Modification of a read-only value attempted at ./test.pl line 31

Question:
1) Why do I get this "Modification of a read-only value attempted" error?
2) Why doesn't the same error show at Line 24?

I don't see any difference between line 24 and line 31.

Thanks for the help.
 
Hi

Good questions. No answers from me.

My guess is, a dereferencing failure is misinterpreted in that module.
[ul]
[li]Line 28 would also throw error in case you would try to check an item of the undefined [tt][navy]$readOnlyHash1[/navy][teal]{[/teal][navy]$k1[/navy][teal]}{[/teal][navy]$k2[/navy][teal]}[/teal][/tt], like [tt][navy]$readOnlyHash1[/navy][teal]{[/teal][navy]$k1[/navy][teal]}{[/teal][navy]$k2[/navy][teal]}{[/teal]huh[teal]}[/teal][/tt].[/li]
[li]Line 31 would not crash either if you would use the [tt]->[/tt] operator, like [tt][navy]$readOnlyHash2[/navy][teal]->[/teal][teal]{[/teal][navy]$k1[/navy][teal]}[/teal][teal]->[/teal][teal]{[/teal][navy]$k2[/navy][teal]}[/teal][/tt].[/li]
[/ul]
This is what makes me believe in fact is a dereferencing error in the background. ( Which belief not necessary has anything to do with the reality… )

By the way, the manual says
man perlfunc said:
Use of [tt]defined[/tt] on aggregates (hashes and arrays) is deprecated.
But using [tt]exists[/tt] instead changes nothing in this case.

Feherke.
feherke.github.io
 
Thank you Feherke for your input and for your reminding me using exists instead of defined.
Sorry for this delayed follow-up.
 
Hi Feherke,

I retested the code using hash ref as you suggested. I got the same error.

Below is my code - 2 red lines are new.

Code:
#!/usr/bin/perl -w

use strict;
use Readonly;

Readonly::Hash my %readOnlyHash1_v => (
  'key11'=>{
    'key21'=>1,
    'key22'=>1,
  },
  'xyz'=>{
    'abc'=>1,
  },
);
[b][COLOR=red]Readonly::Scalar my $readOnlyHash1 => \%readOnlyHash1_v;[/color][/b]

Readonly::Hash my %readOnlyHash2_v => (
  'xyz'=>{
    'abc'=>1,
  },
);
[/color][/b]Readonly::Scalar my $readOnlyHash2 => \%readOnlyHash2_v;[/color][/b]

my $k1 = 'key11';
my $k2 = 'key31';
if(exists($readOnlyHash1->{$k1}->{$k2})) { [b]# line 26[/b]
  print "exists: Key 1 - $k1, Key 2 - $k2\n";
}
else {
  print "Not exists: Key 1 - $k1, Key 2 - $k2\n";
}

if(exists($readOnlyHash2->{$k1}->{$k2})) { [b]# line 33[/b]
  print "exists: Key 1 - $k1, Key 2 - $k2\n";
}
else {
  print "Not exists: Key 1 - $k1, Key 2 - $k2\n";
}

And the output:
Code:
% ./test.pl
Not exists: Key 1 - key11, Key 2 - key31
Modification of a read-only value attempted at ./test.pl line 33

Thank you for your time and help.

 
In the second hash, [tt]$k1[/tt] does not exist, but, to test the existence of [tt]$readOnlyHash2->{$k1}->{$k2}[/tt], [tt]$readOnlyHash2->{$k1}[/tt] must be created, whence the error. You should write:
Code:
if(exists($readOnlyHash2->{$k1}&&exists($readOnlyHash2->{$k1}->{$k2})) {

: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
I see! Thank you, prex!

I thought if(exists($readOnlyHash2->{$k1}->{$k2})) would automatically test if(exists($readOnlyHash2->{$k1})) first.

Thanks again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top