How do I tell what type of value is in a Perl variable?

前端 未结 5 2136
旧时难觅i
旧时难觅i 2020-12-02 16:52

How do I tell what type of value is in a Perl variable?

$x might be a scalar, a ref to an array or a ref to a hash (or maybe other things).

5条回答
  •  广开言路
    2020-12-02 16:58

    At some point I read a reasonably convincing argument on Perlmonks that testing the type of a scalar with ref or reftype is a bad idea. I don't recall who put the idea forward, or the link. Sorry.

    The point was that in Perl there are many mechanisms that make it possible to make a given scalar act like just about anything you want. If you tie a filehandle so that it acts like a hash, the testing with reftype will tell you that you have a filehanle. It won't tell you that you need to use it like a hash.

    So, the argument went, it is better to use duck typing to find out what a variable is.

    Instead of:

    sub foo {
        my $var = shift;
        my $type = reftype $var;
    
        my $result;
        if( $type eq 'HASH' ) {
            $result = $var->{foo};
        }
        elsif( $type eq 'ARRAY' ) {
            $result = $var->[3];
        }
        else {
            $result = 'foo';
        }
    
        return $result;
    }
    

    You should do something like this:

    sub foo {
        my $var = shift;
        my $type = reftype $var;
    
        my $result;
    
        eval {
            $result = $var->{foo};
            1; # guarantee a true result if code works.
        }
        or eval { 
            $result = $var->[3];
            1;
        }
        or do {
            $result = 'foo';
        }
    
        return $result;
    }
    

    For the most part I don't actually do this, but in some cases I have. I'm still making my mind up as to when this approach is appropriate. I thought I'd throw the concept out for further discussion. I'd love to see comments.

    Update

    I realized I should put forward my thoughts on this approach.

    This method has the advantage of handling anything you throw at it.

    It has the disadvantage of being cumbersome, and somewhat strange. Stumbling upon this in some code would make me issue a big fat 'WTF'.

    I like the idea of testing whether a scalar acts like a hash-ref, rather that whether it is a hash ref.

    I don't like this implementation.

提交回复
热议问题