Joe Schaefer wrote:
Stas Bekman <[EMAIL PROTECTED]> writes:

[...]


Check this out. It seems to work now. Here is a complete patch.
You will have to rebuild the whole thing, because of the API change.


[...]


+static MP_INLINE
+const char *mpxs_APR__Table_FETCH(pTHX_ SV *tsv, const char *key)
+{
+    apr_table_t *t = mp_xs_sv2_APR__Table(tsv);
+
+    if (!t) {
+        return "";
+    }
+
+    if (!mpxs_apr_table_iterix(tsv)) {
+        return apr_table_get(t, key);
+    }
+    else {
+        const apr_array_header_t *arr = apr_table_elts(t);
+        apr_table_entry_t *elts  = (apr_table_entry_t *)arr->elts;
+        return elts[mpxs_apr_table_iterix(tsv)-1].val;
+    }
 }


Although I haven't tested the patch, I still don't think this is a good approach. The problem is that this introduces "state" into
FETCH, and normal perl hashes don't have this. Look at this
(albeit contrived) example:


# do something to each entry until the "foo" key is encountered

sub foo_do { my $t = shift;
my ($k, $v) = each %$t; return if not defined $k or $k eq "foo";


    # ...do stuff here...
  }

foo_do($t);

my $bar = $t->{bar}; # do we get foo's value here, or bar's value ?
If the "foo" key is ever present in $t, the iterator state (SvCUR)
for $t will remain positive, so a subsequent normal FETCH will
not produce accurate results. $bar will likely wind up holding foo's value here.


With a normal hash, there's no problem here because perl calls hv_iterval (not hv_fetch) when it wants to do an "iterative" fetch.

It seems to me that the TIEHASH API isn't as flexible as it needs to be- IMO it _should_ call FIRST_KEY and NEXT_KEY in list context when it needs to produce each(%$t) (or values (%$t)) in a list context (of course, it doesn't- all TIE methods are called in
scalar context by the Perl_magic_*pack functions in mg.c.

That's true. My "fix" takes it a bit further, but as your example shows it introduces the state problem. The solution I see is to store the id in the key, so when FETCH is called in the SCALAR context it checks whether the key has an id and uses it to get the appropriate value. Otherwise it calls apr_table_get(). Does this work? This is in addition to the existing each/keys solution.




__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to