开发者

What is Perl equivalent of Python's type() function [duplicate]

开发者 https://www.devze.com 2023-02-14 09:09 出处:网络
This question already has answers here: 开发者_运维技巧How do I tell what type of value is in a Perl variable?
This question already has answers here: 开发者_运维技巧 How do I tell what type of value is in a Perl variable? (5 answers) Closed 9 years ago.

I can do this in Python:

>>> type(1)
<class 'int'>

What's the Perl equivalent?


Perl does not make a hard distinction between strings and numbers the way that Python or Ruby do. In Perl, the use of operators determines how the variable will be interpreted.

In Python, when you write 1 + 2, Python checks the type of each argument, sees that they are numbers, and then performs the addition (3). If you write '1' + '2', it sees that both are strings, and performs concatenation ('12'). And if you write 1 + '2' you get a type error.

In Perl, when you write 1 + 2, the + operator imposes numeric context on it's arguments. Each of the arguments is converted to a number (with a subsequent warning if the argument could not be converted cleanly) and then the addition is performed (3). If you write '1' + '2', the arguments are still converted to numbers with a result of 3.

If you wanted concatenation, you would use the . operator: 1 . 2 which will result in '12' even though both of the arguments were numbers.

So since Perl's operators force a type interpretation, the variable itself does not need to (and doesn't) contain a type. If you really need to determine which is which, you can use Scalar::Util's looks_like_number function, but generally coding like that in Perl is indicative of a design problem.

Perl's scalar variables can contain one of 4 things:

  • numbers
  • strings
  • the undefined value (undef)
  • references (which can be a reference to any of the primitive types, or to objects)

The ref keyword is used to determine if a scalar contains a reference, and what type that reference is.

ref(1)         --> ''  (a false value)
ref('string')  --> ''  (a false value)
ref([1, 2, 3]) --> 'ARRAY'
ref({a => 1})  --> 'HASH'
ref(\1)        --> 'SCALAR'
ref(\\1)       --> 'REF'
ref(sub {})    --> 'CODE'

The full list can be found at perldoc -f ref

When a reference is blessed into a package, that reference becomes an object. In that case, ref will return the name of the package the object is blessed into.

{package My::Object;
    sub new {bless {}}
}

my $obj = My::Object->new;

ref($obj)  -->  'My::Object'


Try ref.


  • Params::Util::_POSINT is a good, standard way of checking if a scalar is a positive integer.
  • Params::Util::_NONNEGINT is a good, way of checking if a scalar is a positive integer or 0.

I'm not sure why there is not an _INTEGER function.

If you are dealing with objects, then Scalar::Util::blessed is the modern way of checking. It does what ref does, but does not return a value for unblessed references. (Which is what objects are in Perl.)


The beauty of Perl and TIMTOWTDI (YMMV) is that you can make it what it do what you want by combining the sniffing methods. Stick it in a module and reuse it.


You can use 'isa' to test whether a target belongs to a specific class (but you have to ask if it is, not what is it). 'ref' can be used to find out what type of data a reference is, or if it isn't a reference at all.

AFAIK, there is not real equivalent because typing doesn't mean the same thing in Perl as it does in Python.


If you want to check if something is an integer you could try the following:

use Scalar::Util;

if ( defined $value
  && !ref $value 
  && ref \$value eq 'SCALAR' 
  && Scalar::Util::looks_like_number($value)
  && $value =~ /^-?[0-9]+$/msx
) {
    printf '%s is an integer', $value;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消