develooper Front page | perl.perl5.porters | Postings from July 2013

key/value hash slices summary

Thread Next
From:
Ruslan Zakirov
Date:
July 1, 2013 13:05
Subject:
key/value hash slices summary
Message ID:
CAMOxC8sFapXC=Y4RPgfULRG67-eYM4WiPcv_FDej47UwGsWOzQ@mail.gmail.com
Hi,

Collected summary on the subject (below). At this moment lvalue subs are
treated as written in the doc, but everything else should be. Edge cases to
add to tests are more than welcome.

Key/value hash slices and index/value array slices
  Syntax
    Just like existing slice operations.

        my %sub = %hash{'a', 'b', 'c'};

  Why a new syntax?
    New syntax fits within existing syntax for slices and completes the
    picture.

        my $scalar = $h{'a'};
        my @list = @h{'a', 'b'};
        my %hash = %h{'a', 'b'};

    First two from above exist for ages, the third fits natural. I don't see
    any other reasonable behaviour for the third.

  Why not a function?
        my %second = slice %first, qw/a c/;

    It's sure possible to implement this as function, but I feel it fits.

  But Perl 6?
    Sigils in Perl 6 have different meaninging and it's radical change from
    Perl 5, so this argument is hardly applicable..

  Not existing keys
    If a key doesn't exist then undef is returned. However, it doesn't
    create a new record in the source.

        my %first = (a => 1, b => 2);
        my %second = %first{qw/a c/};

    Entry with "c" key exists in %second and its value is "undef". It's very
    easy to skip not existing keys:

        my %second = %first{ grep exists $first{$_}, qw/a c/ };

    Behaviour is consistent with existing slices and other operations.

  Scalar context
    Operator returns list, so in scalar context last value is used.

        my $e = %h{ "foo", "bar" };

    Above is "equivalent" of "$e = $h{'bar'}".

    By luck the following "red eyes mistake" result in what most people
    expect:

        my $s = %hash{'a'};

  Interpolation in strings
    "%" is not treated specially in strings, so key value slices are not
    interpolated in any way.

  Left value
    Most explicit lvalue operations on key/value hash slices throw errors:

        %h{qw(a b)} = qw(A B);

    Even:

        %h{'a'} = 'foo';

    Above is not scalar assignment as left hand side is a list, so it's also
    fatal.

    This also means that operation can not be used as result of lvalue sub.

    Exceptions are grep, map, foreach operations as the following should
    behave similar, even if it's questionable:

        $_++ for %hash;
        $_++ for %hash{'a', 'b'};

  Warnings
    *
            Scalar value %h{i} better written as $h{i}

        Can be workarounded.

  Errors
    *   Localizing hash slices is not allowed, the following fails:

            local %h{qw/a b/};

    *   You can not use these slices as left hand side of assignment op:

            %h{'a', 'b'} = qw(A B);
            %h{'a'} = 'value';

    *   delete is not allowed, the following fails:

            my %sub = delete %hash{'a', 'b'};

        So far above code dies and suggests to use hash slice, but it can be
        re-considered.


-- 
Best regards, Ruslan.


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About