in reply to Re^3: Importing multiple %EXPORT_TAGS
in thread Importing multiple %EXPORT_TAGS

Great catch!

However, the separation isn't needed. As soon as I saw you put the EXPORT_OK into an anonymous array, changed from the taking of the reference as I had it, I realized that's all that was needed. So all now instead of being a reference to the array, it's a reference to a copy of it:

our %EXPORT_TAGS = ( all => [ @EXPORT_OK ], private => _export_private(), ); sub _export_private { push @EXPORT_OK, @EXPORT_PRIVATE; return \@EXPORT_OK; }

Output:

$VAR1 = { 'private' => [ 'add_bugtracker', 'add_repository', 'changes', 'changes_bump', 'changes_date', 'ci_badges', 'ci_github', 'git_ignore', 'init', 'make_test', 'manifest_skip', 'move_distribution_files', 'remove_unwanted_files', 'version_bump', 'version_info', '_git_commit', '_git_push', '_validate_git' ], 'all' => [ 'add_bugtracker', 'add_repository', 'changes', 'changes_bump', 'changes_date', 'ci_badges', 'ci_github', 'git_ignore', 'init', 'make_test', 'manifest_skip', 'move_distribution_files', 'remove_unwanted_files', 'version_bump' 'version_info', ] };

Replies are listed 'Best First'.
Re^5: Importing multiple %EXPORT_TAGS
by jcb (Parson) on Dec 29, 2020 at 03:52 UTC

    I am fairly sure the separation is needed, unless you can point to documentation somewhere that says the values used to initialize a hash will always be evaluated left-to-right. Otherwise, your code may work now, but is relying on undefined behavior and may stop working in a future version of perl.

    The problem is that _export_private modifies @EXPORT_OK, so the order in which [@EXPORT_OK] and _export_private() are evaluated matters. If the list values are evaluated right-to-left in some future version of perl, you will be right back where you were, as the internal functions will be added to @EXPORT_OK just before the array is copied for the :all tag.