Vivek Dasmohapatra wrote:

On Mon, 10 Mar 2003, Steve Hay wrote:



Hi,

I have a hash which stores numerical data and I want to increase the
values by variable amounts each time round a loop.

At the moment, I am fetching the value to an SV, coercing that into an
IV, increasing the value, and then making a new SV from that to store
back into the hash:

HV *hash;
int total;
int num;
...
total = SvIV(*hv_fetch(hash, "total", 5, 0));
total += num;
hv_store(hash, "total", 5, newSViv(total), 0);



Something like (not tested):


#define H_CREAT 1
#define H_FETCH 0

SV **hval;
int tot;
int num;
...
hval = hv_fetch(hash, "total", 5, H_CREAT);
if( hval )
{
if( SvOK(*hval) )
{
tot = SvIV(*hval) + num;
sv_setiv(*hval, tot);
}
else
{
hv_store(hash, "total", 5, newSViv(num), 0);
}
}


Yes, this works.

I think the mistake in my attempted use of sv_inc() was to call hv_store() afterwards, rather like inserting

hv_store(hash, "total", 5, *hval, 0);

after the sv_setiv() call in your code snippet above.

Presumably, then, *hval (an SV *) is a pointer to the value actually held in the hash, so having modified the value through that pointer there is no need to store it back in the hash. Is this correct? (I had been thinking that the SV * was disassociated from the hash so that after changing it, I would need to store it back.)

Having said all that, however, it may be easier just to accumulate this data in simple C arrays and then copy it all to the Perl hash when I've finished.

Thanks,

Steve



Reply via email to