On Thu, 15 May 2008 13:21:34 +0100, Tim Bunce <[EMAIL PROTECTED]> wrote:
> I'm sorry for the delay in responding Rudy.
>
> On Wed, May 07, 2008 at 02:34:43AM -0400, Rudy Lippan wrote:
>
>> use Scalar::Util qw(looks_like_number);
>> sub _get_sorted_hash_keys {
>> my ($hash_ref, $sort_type) = @_;
>> my $sort_guess = 1;
>> $sort_guess = 1!=looks_like_number($_) ? 0:$sort_guess for keys
> %$hash_ref;
>> $sort_type = $sort_guess unless (defined $sort_type);
>
> You don't need to calculate $sort_guess unless $sort_type is undef.
>
I know. The code is only used for testing against the C implementation, and
putting it inside the #if defined($sort_type) made the code wrap ;)
Changed.
>> my @keys = keys %$hash_ref;
>> no warnings 'numeric';
>> my @keys = ($sort_type && $sort_guess)
>> ? sort {$a <=> $b} @keys
>> : sort @keys;
>
> Duplicate "my @keys" declarations.
>
Fixed. And looking over the code, I also should go back and strictify...
>
> No need for dTHX there.
>
> or here.
>
expurgated.
>> +char **
>> +_sort_hash_keys (hash, sort_order, total_length)
>> +{
>
>> + while ((entry = hv_iternext(hash))) {
>> + *(keys+idx) = hv_iterkey(entry, &key_len);
>> + tot_len += key_len;
>> +
>> + look_num_sv = sv_2mortal(newSVpv(*(keys+idx),0));
>> + if (1 == looks_like_number(look_num_sv))
>> + *(numbers+idx) = (int)SvIV(look_num_sv);
>> + else
>> + numberish = 0;
>
> You could avoid the expensive sv_2mortal(newSVpv()) by replacing those 5
> lines with something like this:
>
> if (grok_number(*(keys+idx), key_len, numbers+idx) ==
IS_NUMBER_IN_UV)
> numberish = 0;
>
> (The numbers array would need to be UV's, but that's no problem.)
>
I like that. grok_number(): I must remember that one..
>> + if (0 == sort_order || 0 == numberish ) {
>> + qsort(keys, hv_len, sizeof(char*), _cmp_str);
>> + } else {
>> + qsort(numbers, hv_len, sizeof(int), _cmp_number);
>> + for (idx = 0; idx < hv_len; ++idx)
>> + *(keys+idx)
> =SvPV(sv_2mortal(newSViv(numbers[idx])),key_len);
>
> It would be good to add a clear comment somewhere that the pointers in
> the keys array are only valid until perl next free mortal temps.
> (There are faster ways of doing that but the use case for the numeric
> keys isn't speed critical.)
>
Suck as, if you don't mind me asking?
>> +_concat_hash_sorted (hash, kv_sep_sv, pair_sep_sv,
> value_format_sv,sort_type_sv)
>> + PREINIT:
>> + CODE:
>
> I'd be grateful if you could refactor this so the bulk of the code is in
> a C function and the XS is just a small wrapper. Would make it easier to
> use for the ShowErrorStatement code (around line 3387).
Sure. leave params to the C function as SV *?
>
> Thanks again for all your work on this Rudy!
No problem. It has been a few years since I have done any C/XS coding,
and I am trying to get back in the swing. Thank you for the suggestions.
>
> p.s. I've already committed the sv_2mortal change in neatsvpv() - but in
> a different way, so you can drop that hunk from the patch before you
> apply the patch to the trunk.
I caught that after I applied it against trunk -- it took me a few minutes
to
figure out why I was getting double frees :)
-r