Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I turn the Perl 5 module Data::Printer's `show_tied` option off when using it in Raku?

I've used the CPAN Perl module Data::Printer (DP) with Perl. It works great.

Now I want to use it in Raku code.

When I use the :from<Perl5> feature to import it and then run code using it, the annotation (tied to Perl6::Hash) is appended to the display of hashes.1

As DP's CPAN doc shows, this annotation is controlled by the option show_tied. I want to switch it off (set it to 0) instead of its default on (set to 1). Here's how I'd do that in Perl:

use Data::Printer show_tied => 0;

But when I try this in Raku:

use Data::Printer:from<Perl5> show_tied => 0;

I get:

Error while importing from 'Data::Printer': no such tag 'show_tied'

How do I turn show_tied off when using DP in Raku?

Footnotes

1 Perhaps this is because Inline::Perl5 (which implements the :from<Perl5> feature) is doing something to enable smooth Perl/Raku interop.

like image 715
raiph Avatar asked Jan 01 '20 22:01

raiph


1 Answers

How do I turn show_tied off when using DP in Raku?

You must explicitly convert Associatives (eg Pairs) that are listed at the end of a use statement, that are not "tags", to a flattened list interleaving keys and values.1

The most direct solution is to manually write a flat list of literals, eg:

use Data::Printer:from<Perl5> 'show_tied', 0;

For a neater solution, see the Using kv section below.

Injecting variables

Note that use statements are evaluated at compile-time. So if you want to inject variables in the list then you need to ensure that their values, not just their names, are also established at compile-time, before the use statement is evaluated. An unadorned my $foo = 0; will not suffice because the = 0 part will happen at run-time. Instead you will need to use a suitable compile-time construct such as BEGIN:

BEGIN my $foo = 0;
use Data::Printer:from<Perl5> 'show_tied', $foo;

Using kv

The kv routine can generate the desired 'key1', value1, 'key2', value2, ... sequence given a hash:

use Data::Printer:from<Perl5> kv { show_tied => 0 }

or:

BEGIN my %opts = show_tied => 0;
use Data::Printer:from<Perl5> kv %opts;

Footnotes

1 This answer built upon Stefan's explanation from the issue I opened in response to the "Altering parameters in Data::Printer in Raku" SO:

The solution is rather simple: use Data::Printer:from<Perl5> 'show_tied', 0; The fat comma => is a Pair constructor in Raku while it's really just a fancy comma in Perl 5. Raku considers Pair arguments to be used for importing tags like :ALL (which is equivalent to ALL => True). To get around this and pass what Perl 5 code expects, just list the values individually.

In other words, this need for conversion is because Perl and Raku share the notion of tags (Perl doc about "tags"; Raku doc about "tags") and (not coincidentally) idiomatically use the same syntax for selecting tags (:tagname).

Furthermore, using Raku, this issue of (the need to resolve) ambiguity between whether syntax is being used to specify tags or not applies to all Associatives used in the top level of a use statement, not just ones written in the form :foo but even ones written in other forms such as foo => bar, { foo => bar}, %baz, or { %baz }.

like image 190
raiph Avatar answered Nov 01 '22 19:11

raiph