ярлык для именованных параметров из соответственно названных переменных - PullRequest
0 голосов
/ 22 декабря 2018

Моя функция

use 5.028;
use strictures;
use Kavorka qw(fun);

fun foobar(:$foo, :$bar) { say $foo, $bar; }

Мне нужно передать ей именованные аргументы, а не позиционные аргументы.

foobar('quux', 'quuuux');
# Unknown named parameter: quux at … line 5.
#         main::foobar("quux", "quuuux") called at … line 7

, но

foobar(foo => 'quux', bar => 'quuuux');
# ok

Hash esили HashRef s также принимаются.

my %args = (foo => 'quux', bar => 'quuuux');
foobar(%args);
my $args = {foo => 'quux', bar => 'quuuux'};
foobar($args);

В ES6 существует ярлык, в котором переменные в литерале объекта раскрываются (изд: ссылка MDN?):

function foobar({foo, bar}) { console.log(foo, bar); }
foobar({foo: 'quux', bar: 'quuuux'});
const foo = 'quux';
const bar = 'quuuux';
foobar({foo: foo, bar: bar});
foobar({foo, bar}); // NB!

В Perl 6 переменная : с префиксом в сигнатуре параметра создаст ключ с тем же именем :

use v6;
sub foobar(:$foo, :$bar) { say $foo, $bar; }
foobar(foo => 'quux', bar => 'quuuux');
my $foo = 'quux';
my $bar = 'quuuux';
foobar(foo => $foo, bar => $bar);
foobar(:$foo, :$bar); # NB!

Как можно сделать что-то сопоставимоедействует для Perl 5?

my $foo = 'quux';
my $bar = 'quuuux';
foobar(???);

1 Ответ

0 голосов
/ 03 июня 2019

У меня есть несколько способов сделать это, используя либо PadWalker (спасибо за моб за предложение), либо Hash Slices:

use strict;
use warnings;
use Data::Dumper;
use PadWalker qw/ var_name /;

sub test_sub { print Dumper [ @_ ] }

my %vars;

$vars{foo} = "foo_data";
$vars{bar} = "var_data";

test_sub( %{vars}{qw/ foo bar/} );

# nv = named variables ( rename as needed )
sub nv { map { ( substr( var_name(1, \$_), 1) => $_ ) } @_ }

my $foo = 'foo_stuff';
my $bar = 'bar_stuff';

test_sub( nv( $foo, $bar ) );

, что дает:

$VAR1 = [
          'foo',
          'foo_data',
          'bar',
          'var_data'
        ];
$VAR1 = [
          'foo',
          'foo_stuff',
          'bar',
          'bar_stuff'
        ];

Пришлосьсделайте субстрат в nv, иначе он показывает сигил, но это лучшее, что я могу придумать, не вдаваясь в более глубокую магию.

Без использования nv это потребует более глубокой магической манипуляции ...

Использование вашего кода Kavorka:

use 5.020;
use strictures;
use Kavorka qw(fun);
use PadWalker qw/ var_name /;

fun foobar(:$foo, :$bar) { say $foo, $bar; }

my %vars;

$vars{foo} = "foo_data";
$vars{bar} = "var_data";

foobar( %{vars}{qw/ foo bar/} );

# nv = named variables ( rename as needed )
sub nv { map { ( substr( var_name(1, \$_), 1) => $_ ) } @_ }

my $foo = 'foo_stuff';
my $bar = 'bar_stuff';

foobar( nv( $foo, $bar ) );

дает:

foo_datavar_data
foo_stuffbar_stuff

У меня не установлено 5.28 локально, к сожалению, хе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...