targetsmart has asked for the wisdom of the Perl Monks concerning the following question:

I have used undef on an hash slice which works as expected, but undef on an array slice is not actually doing so, I have also read this http://www.perlmonks.org/?node=hash+slice, but what I want to know is, if the undef is not a list operator how it works for hashes slices then?.
UPDATE:

Probably I might not have explained the problem correctly, the problem is
if @a = (a,b,c), after undef @a[1,2] we might get a,b as the content o +f @a, which is quite clear, because only $a[2] becomes undef, but con +sider the hash slice case if @a = (a,b,c), undef @a{@a} gives me, undef values properly for the +keys a,b and c, how is this possible?, I thought that as per array sl +ice effect it should only undef $a{c} isn't it?.

-- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.

Replies are listed 'Best First'.
Re: Hash slice again
by ikegami (Patriarch) on Jan 27, 2009 at 14:00 UTC
    Works for me
    >perl -le"@a=qw(a b c d e); undef @a[2,3]; print for @a" a b c e

    Update: Wait, I guess it didn't work for me. (Sorry, was rushed.) You can use this:

    >perl -le"@a=qw(a b c d e); undef $_ for @a[2,3]; print for @a" a b e

    The docs are quite specific as to what undef accepts for args. I would expect a built-in to complain if you gave it incorrect arguments, but that's what you are doing.

    By the way, undef @h{@k}; is not allowed and doesn't work either.

    $ perl -le"%h=map { $_=>$_ } qw(a b c d e); undef @h{qw( c d )}; print + qq{$_: $h{$_}} for sort keys %h" a: a b: b c: c d: e: e
Re: Hash slice again
by lostjimmy (Chaplain) on Jan 27, 2009 at 14:23 UTC
    Maybe you still haven't explained the problem correctly. When I undef a hash slice, only one of the values becomes undefined, and when I undef an array slice, only the last element becomes undefined.
    use Data::Dumper; my @a = qw/a b c d e/; my %a; @a{@a} = (1) x @a; print "--- \@a before ---\n", Dumper \@a; print "--- \%a before ---\n", Dumper \%a; undef @a{@a}; undef @a[1,2,3]; print "--- \@a after ---\n", Dumper \@a; print "--- \%a after ---\n", Dumper \%a;
    Yields this output:
    --- @a before --- $VAR1 = [ 'a', 'b', 'c', 'd', 'e' ]; --- %a before --- $VAR1 = { 'e' => 1, 'c' => 1, 'a' => 1, 'b' => 1, 'd' => 1 }; --- @a after --- $VAR1 = [ 'a', 'b', 'c', undef, 'e' ]; --- %a after --- $VAR1 = { 'e' => undef, 'c' => 1, 'a' => 1, 'b' => 1, 'd' => 1 };
      use strict; use warnings; use Data::Dumper; my @a = qw/a b c d/; my @b = qw/a b c d/; my %a; print '--- my @a before ---',"\n", Dumper \@a; undef @a[1,2]; print '--- my @a after ---',"\n", Dumper \@a; print '--- my %a before ---',"\n", Dumper \%a; undef @a{@b}; print '--- my %a after ---',"\n", Dumper \%a;
      the above code prints
      --- my @a before --- $VAR1 = [ 'a', 'b', 'c', 'd' ]; --- my @a after --- $VAR1 = [ 'a', 'b', undef, 'd' ]; --- my %a before --- $VAR1 = {}; --- my %a after --- $VAR1 = { 'c' => undef, 'a' => undef, 'b' => undef, 'd' => undef };

      When I undef a hash slice, all the values becomes undefined, and when I undef an array slice, only the last element becomes undefined.
      Why is it so is the question?.
      UPDATE
      The question can be asked like this, why the undef behaves differently when it is a new array/hash, compared to when it sees an existing array/hash
      if @a = (1,2,3), then undef @a[1,2] is proper, undefines $a[2] just undef @b[2], is giving me @b's 0 ,1 and 2 indexes to be undef. if %hash = qw(a b c d) then undef @hash{qw(a c)} is proper, undefines + only $hash{c} just undef @hash1{qw(a c}} is giving me the values of the keys a and c + to be undef

      -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.

        You are creating hash elements with undef @a{@b}. This is called autovivication (see wikipedia for a nice explanation) and has nothing to do with the undef function. Something similar happens when you write @a{@b}= (1);. The hash would contain key a set to 1 and keys b and c set to undef

Re: Hash slice again (NOT)
by rir (Vicar) on Jan 28, 2009 at 21:05 UTC
    In your update, you are mixing up arrays and hashes. You imply this code, which you should have shown to your helpful friends use strict and use warnings:
    @a = (a,b,c); undef @a[1,2]; @a = (a,b,c);
    undef @a{@a};# there is no hash you probably want something like this:
    @array = ( 'a', 'b', 'c', 'd', 'e' ); %hash = ( a => 0, b => 1, c => 2, d => 3, e => 4 ); @indices = ( 2, 3); @keys = ( 'c', 'd' ); undef @array[ @indices ]; # undefs value of/in @array[3] undef @hash{ @keys }; # undefs value of/in $hash{d} use Data::Dumper; print Dumper \%hash; print Dumper \@array; __END__ $VAR1 = { 'e' => 4, 'c' => 2, 'a' => 0, 'b' => 1, 'd' => undef }; $VAR1 = [ 'a', 'b', 'c', undef, 'e' ];
    Be well,
    rir

      He's asking why 'c' is still in the array. Even with your fix, it's still in the array.