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

I have the following routine:

sub remap { my %remap = qw{ THIS THAT BLACK WHITE TALL SHORT }; $remap{ $_[0] }; }

Put in TALL, get out SHORT... The use of a lexical sort of strikes me as being a little unnecessary, what I would like to do would be to just build an anonymous hash out of the qw list, and dereference it:

sub remap_anon { @{[qw{ THIS THAT BLACK WHITE TALL SHORT }]}->{$_[0]}; }

Cool! That actually compiles. I was tickled pink. Trouble is, I don't know what it does. It certainly doesn't do what I want it to. If I try to run it I get: Can't coerce array into hash at remapper line 15

So I googled around a bit, and the only solutions I see are what I had in the first place: dump the list into a hash and then dereference it. Drat. I tried enclosing the anonymous @{[...]} in an outer %{...] or even %{[...]}, but perl continues to choke with the same message. At this stage it's just shotgun debugging, and besides, the syntax is a net loss.

So my question is, even if perl can't do it by itself (because "You used an array where a hash was expected, but the array has no information on how to map from keys to array indices. You can do that only with arrays that have a hash reference at index 0"), is there a way to coerce perl to coerce an array into a list? And what does that message really mean?


print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

Replies are listed 'Best First'.
Re: Coercing an array into a hash
by broquaint (Abbot) on Dec 05, 2002 at 12:10 UTC
    Try
    sub remap_anon { return {qw( THIS THAT BLACK WHITE TALL SHORT )}->{$_[0]}; }
    There you're creating an anonymous hash, populating it with the list and dereferencing the result, simple as that!
    HTH

    _________
    broquaint

Re: Coercing an array into a hash
by Zaxo (Archbishop) on Dec 05, 2002 at 12:41 UTC

    A third way,

    { my $remap = { qw( THIS THAT BLACK WHITE TALL SHORT ) }; sub remap_closure { exists $remap->{ $_[0] } ? $remap->{ $_[0] } : undef; } }
    By checking for existence, the hash does not keep growing new undefined keys as possibles are tried. That is not a problem with the others since each invocation gets a new hash with them.

    After Compline,
    Zaxo

Re: Coercing an array into a hash
by PodMaster (Abbot) on Dec 05, 2002 at 12:17 UTC
    I'd revisit perl perldata/perlref and family (cause I forget in which [] and {} are discussed, anyway ;)
    sub FU { return { qw[ a b c d ] }->{$_[0]}; } die FU('a'); __END__ b at - line 5.

    update:

    Oh yeah, I almost forgot, you don't have an array, you have a list.


    MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
    ** The Third rule of perl club is a statement of fact: pod is sexy.