DEV Community

Cover image for Tools for learning Perl context
kobaken
kobaken

Posted on

Tools for learning Perl context

There are times when I am confused by the context of Perl. I wrote a tool to reduce this confusion.

GitHub logo kfly8 / p5-Contextual-Diag

diagnose contexts

Usage

If you plug in the contextual_diag subroutine where you want to know Perl context, it will alert you to the context.

The following code explores the context when evaluating the value of a hash reference:

use Contextual::Diag;

# Here...
my $a = { key => 'value' };

# Do this...
my $a = { key => contextual_diag 'value' };

# Then this happens!
# => wanted LIST context
Enter fullscreen mode Exit fullscreen mode

Inside Contextual::Diag

In Contextual::Diag, the first step is to use wantarray to separate contexts into SCALAR, LIST, and VOID. Then, in the case of SCALAR context, the return value is wrapped in an object, and overload is used to hook into string evaluation, numeric evaluation, and array dereferencing. Only in the case of object reference, overload is not enough to hook, so AUTOLOAD is used. I got this idea from Professor Damian's Contextual::Return.

List of diagnoses

Contextual::Diag has a total of 11 different diagnoses:

1. SCALAR context
   - CASE: Scalar value
      - BOOL e.g. `if ($value)`
      - NUM e.g. `$value + 1`
      - STR e.g. `$value . "hello"`
   - CASE:  Scalar reference
      - SCALARREF e.g. `$$value`
      - ARRAYREF e.g. `$value->[0]`
      - HASHREF e.g. `$value->{key}`
      - CODEREF e.g. `$value->()`
      - GLOBREF e.g. `*{$value}->{CODE}`
      - OBJREF e.g. `$value->hello()`
2. LIST context
3. VOID context
Enter fullscreen mode Exit fullscreen mode

Conclusion

I wrote Contextual::Diag to make it easier to understand Perl context.

You can use it if you like!

Discussion (4)

Collapse
matthewpersico profile image
Matthew O. Persico

TIL...
I thought the 'value' of a hash must be a scalar value. So I ran:

$ perl -de 42
  DB<5> @arr= qw ( x y z)
  DB<6> $href = { key => @arr }
  DB<7> x $href
0  HASH(0x4068718)
   'key' => 'x'
   'y' => 'z'
Enter fullscreen mode Exit fullscreen mode

Boy, was I shocked when x $href did not yield:

0  HASH(0x4068718)
   'key' => 3
Enter fullscreen mode Exit fullscreen mode

The 'fat comma' fooled me.

Collapse
grinnz profile image
Dan Book • Edited on

The values of hashes indeed must be scalar values; the problem here (which has caused many problems and even vulnerabilities) is that the fat comma doesn't construct a hash, just a list.

Collapse
matthewpersico profile image
Matthew O. Persico

Let me rephrase - I assumed that the right hand side of a fat comma would have context scalar. However, since it just a comma, it has context list.

Collapse
kfly8 profile image
kobaken Author

Thank you for your comment!
I empathize with your situation.