On Mon, 10 Mar 2003, Steve Hay wrote:Yes, this works.
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);
}
}
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
