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

Reply via email to