in reply to Accidentally creating hash elements with grep { defined } on a hash slice

Why does testing for definition of a value create a key?

Bad question. It's not defined that creates it.

>perl -MData::Dumper -e"grep { 0 } @h{qw(a b)}; print Dumper \%h;" $VAR1 = { 'a' => undef, 'b' => undef };

grep aliases $_ to the element being tested. That means is needs something to alias to. That causes the element to be created.

Is there a way around the key creation?

Yes, pass the keys to grep, not the values.

my @defined_values = map $benchmarks{$_}, grep defined($benchmarks{$_}), @BASELINES;

or maybe you really want

my @defined_values = map $benchmarks{$_}, grep exists($benchmarks{$_}), @BASELINES;

Replies are listed 'Best First'.
Re^2: Accidentally creating hash elements with grep { defined } on a hash slice
by ccn (Vicar) on Nov 04, 2008 at 11:35 UTC

    And what about $a, $b in sort? They are aliases also, but keys are not created.

      I was just asking myself exactly that question. Turns out grep requires lvalues, but sort doesn't.

      >perl -MO=Concise -e"@b = grep f, @h{@a}" ... a <@> hslice lKM ->b ... >perl -MO=Concise -e"@b = sort @h{@a}" ... a <@> hslice lK ->b ...

      Notice the "M" for "Modifiable" in the former.

      So that begs the question: Why does grep require lvalues? The difference is:

      >perl -e"@a = grep { $_='!'; 0 } @h{qw(i j)};" >perl -e"@a = sort { $a='!'; 0 } @h{qw(i j)};" Modification of a read-only value attempted at -e line 1.

      But as far as I can tell, there is no good reason.

        Why does grep require lvalues?
        So you can suprise people with what this does:
        perl -e "@in = (1..5); @out = grep { $_++ } @in; print qq{@in}"
        But as far as I can tell, there is no good reason.
        Oh - a good reason? Sorry, haven't got one of them. Move along please, nothing to see here.

        --
        .sig : File not found.

        Thanks both for your replies. I understand the problem now :)