March 2023 Archives

ChatGPT for Perl Learning

How to learn Perl has been an eternal problem for the Perl community. Compared to many other languages that place an emphasis on teaching the basics and using education as a tool for evangelism we've had sporadic efforts along those lines. Given the size of our community and the fact that the best programmers are often in great demand, we have a hard time pumping out the needed docs and examples.

I've been using ChatGPT quite a lot lately and find that although it makes some mistakes it actually churns out pretty decent Perl if given good instructions. For example here's one I did this AM. We just had the dreaded hour shift here in the US and I'm just not up to thinking so I asked Chat GPT:

"write a perl subroutine that accepts two hashrefs and a list. For each item in the item merge the hashrefs by combining the values into an array ref. "

Here's what it pumped out:

sub merge_hashes {
    my ($hashref1, $hashref2, @list) = @_;

    foreach my $item (@list) {
        my @values = ();

        if (exists $hashref1->{$item}) {
            push @values, @{$hashref1->{$item}};
        }

        if (exists $hashref2->{$item}) {
            push @values, @{$hashref2->{$item}};
        }

        $hashref1->{$item} = \@values;
    }
}

Along with the following explanation:

"In this subroutine, we first receive two hashrefs and a list as input. We then iterate over each item in the list and create an empty array to hold the merged values.

We then check if each hashref has a value for the current item. If so, we push all the values for that item into the @values array. We then assign the merged @values array as the value for the current item in the first hashref.

Finally, we return the updated first hashref after all items have been processed.

Note: The original hashref1 is modified in place by this subroutine."

Not too bad. I than asked it to modify the code thus:

"change the subroutine so that the item value can be either a scalar or an array ref. we should normalize all values to arrayref"

And it came up with this:

sub merge_hashes {
    my ($hashref1, $hashref2, @list) = @_;

    foreach my $item (@list) {
        my @values = ();

        # Check if the item value is an array ref or scalar
        if (ref $hashref1->{$item} eq 'ARRAY') {
            push @values, @{$hashref1->{$item}};
        } elsif (defined $hashref1->{$item}) {
            push @values, $hashref1->{$item};
        }

        if (ref $hashref2->{$item} eq 'ARRAY') {
            push @values, @{$hashref2->{$item}};
        } elsif (defined $hashref2->{$item}) {
            push @values, $hashref2->{$item};
        }

        # Normalize the value to an array ref
        $hashref1->{$item} = scalar @values > 1 ? \@values : $values[0] || [];
    }
}

Lastly I asked:

"fix this so that the $item value is undefined we don't get an error"

And it produced:

Although its far from perfect this is a space we should be watching and toying with since it seems to me to be a possible way to help bootstrap programmers that need to or want to get into Perl but are not finding the existing learning and mentoring capacity sufficient.

About john napiorkowski

user-pic I blog about Perl.