LINUX.ORG.RU

Classic Perl-style функция для разыменования неизвестной ссылки в список

 ,


0

1

Когда в очередной раз нонадобилось написать что-то вроде «если пользователь передал ссылку на список, то раскрыть в список, если ссылку на хеш - раскрыть в хеш, иначе - вернуть пустой список» - меня внутренне передёрнуло от 100500-й уродливой конструкции с вложенными iif'ами (которые «condition?valIfTrue:valIfFalse») - и я накатал вот это.

Понимаю, что говнокод, но, блин, мне он кажется дико симпатичным :)

sub deref2list {
 ({'ARRAY'=>sub{ @{$_[0]} },'HASH'=>sub { %{$_[0]} } }->{ref $_[0]} || sub {()})->($_[0]) 
}

Классический пример применения - ситуации когда нужно либо добавить в хеш переданные пользователем дополнительные параметры (если это ссылка на массив или на хеш), либо... ничего не добавлять.

Как-то так:

my $l=[
    {"e"=>"Estonia","f"=>"Finland"},
    ["g"=>"Gvinea-Bissau","h"=>"Holland"],
    "Moonland",
    sub { "MGIMO forever" }
]; 
my %h=("a"=>"Angola",map deref2list($_), @{$l});

★★★★★

Последнее исправление: DRVTiny (всего исправлений: 1)

Зачем так писать? Нечитабельно же. От того, что ты записываешь код в одну строку он не становится быстрее.

Я у себя такой костыль для этого использую:

sub unref {
    my $ref = shift;
    my %result = (
        'HASH'  => sub {
            return %$ref;
        },
        'ARRAY' => sub {
            return @$ref;
        },
        'SCALAR'    => sub {
            return $$ref;
        }
    );
    my $type = ref($ref);
    if ($type) {
        $result{$type}->();
    } else {
        return 0;
    }
}

shell-script ★★★★★
()
Ответ на: комментарий от shell-script

А я допилил свой вариант, чтобы можно было список ссылок принимать на вход:

sub derefOrNothing {
 my $I7={
  'ARRAY'=>sub { @{$_[0]} },
  'HASH'=>sub { %{$_[0]} }
 };
 map {($I7->{ref $_} || sub {})->($_)} @_;
}

В моём случае ссылки на «SCALAR» мне не нужны, так что я их silently дропаю как "", «CODE», «GLOB» и всякие там «Package::SubModule» :)

DRVTiny ★★★★★
() автор топика
Последнее исправление: DRVTiny (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.