Cannot modify read-only value in while loop?

2007-01-19 Thread Richard Jones

Help. I've just stumbled upon a new one to me:

my $ref = [ 1..3 ];
push @$ref, 4;

print Dumper $ref as expected gives:

$VAR1 = [
  1,
  2,
  3,
  4
  ];


But in a DBI context:
while ( my $ref = $sth-fetchrow_arrayref() ) { # $ref is arrayref
  push @$ref, 1; # line xx
}

dies with 'Modification of read-only value attempted at .. line xx'

I can't see the difference here between the two $ref arrayrefs, but Perl 
obviously can. Unfortunately 'use diagnostics' didn't help as I think I 
must be missing something obvious.

 --
ra(dot)jones(at)dpw(dot)clara(dot)co(dot)uk


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: Passing hash into sub routines (should i use reference?)

2007-01-19 Thread Richard Jones

Michael Alipio wrote:

Hi,

Suppose I have this code:

#/usr/local/bin/perl use warnings; use strict; use subs 'verify';

my %where=( Gary = Dallas, Lucy = Exeter, Ian =  Reading, 
Samantha = Oregon );


# Then i open a logfile

open FH, '', $logfile or die Can't open $logfile!: $!;

# Now, for every line in the logfile, I will retrive a particular
string, let's say a person's name and verify if it exists in my hash
above:

while (FH){ (my $person) = $_ =~ /person=(\S+)/; my $personstatus =
verify(\%where,$person);

# And do anything if the personstatus is this and that.


# Now,  on my sub verify, I would like to know if the person exists
in my hash.

sub verify { my $where = shift @_; my $person = shift @_; my
$personstatus;

if (exists $$where{$person}){

$personstatus =1; }else { $personstatus = 0; }

$personstatus; }

Am I thinking as this is how it should be done when passing hashes to
a subroutine? My program doesn't work and I know it has something to
do with the my $personstatus line as well as if (exists
$$where{$person} line. Can you show me the right way of passing
hashes to subroutines? Thanks.

I also tried declaring %where as 'our' so that I can use if (exists
%where{$person} instead of if(exists $$where{person}) but i still
can't make it work.


Do you know if I am making any sense here?

Thanks


Why pass a reference to the same hash for every line of the FH? You 
have declared the %where hash at the top so it's already available to 
the sub-routine. Much simpler:


while (FH) {
  my ($person) = $_ =~ /person=(\S+)/; # are you sure this works?
  my $personstatus = verify($person);
}

sub verify {
  local $_ = shift; # $_ contains $person from while loop

  return $where{$_} ? 1 : 0;
}


Or even simpler, dispose of verify() and just do:

while (FH){
  my ($person) = $_ =~ /person=(\S+)/;
  my $personstatus = $where{$person} ? 1 : 0;
}

The correct way to accept a hashref in a sub-routine is:

sub my_subroutine {
  my $hashref = shift;
  my $something_else = shift;

  # OR:
  my ($hashref, $something_else) = @_;
}
--
ra(dot)jones(at)dpw(dot)clara(dot)co(dot)uk


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: Cannot modify read-only value in while loop?

2007-01-19 Thread Richard Jones

Xavier Noria wrote:

On Jan 19, 2007, at 12:55 PM, Richard Jones wrote:


while ( my $ref = $sth-fetchrow_arrayref() ) { # $ref is arrayref
  push @$ref, 1; # line xx
}

dies with 'Modification of read-only value attempted at .. line xx'


Yes, that reference has a flag READONLY turned on, this is a dump of an 
example I ran to figure this out (attached below):


OK, thanks - good to know it's a DBI thing rather than something I did. 
Pushing onto an array instead of an arrayref works just as well in this 
context so it's not a major problem.



--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/