snakespan
snakespan

Reputation: 1211

Perl: Limiting characters on String Scalar variables

I'm looking to ensure the number of characters on a given value are less than 1000. My function is unsure whether the value is an array, hash or scalar.

if (ref($value) eq 'SCALAR' && length($value) >= 1000 ) {
    return;
}

However, what happens if a number is passed in? Will I be unknowingly converting a number value to a string, and if so, is there a way of checking for a numeric value before checking its length?

Upvotes: 0

Views: 191

Answers (2)

simbabque
simbabque

Reputation: 54373

In your question, you are saying that you check the number of characters in a string, and that the variable containing it could also be a hash ref or array ref.

if (ref($value) eq 'SCALAR' && length($value) >= 1000 ) {
    return;
}

However, your code does not check the length of the string or number. It assumes the variable might be a scalar reference, but then checks the length of the stringification of the scalar reference.

say \"asdf";
# SCALAR(0x268e7f8)

say length \"asdf";
# 17

This length should always be 17 on 64 bit systems, or 16 on 32 bit systems.


Once you actually dereference your scalar reference, the following will apply.

#                                     here  and here
#                                      ##        #
if (ref($value) eq 'SCALAR' && length( ${ $value } ) >= 1000 ) {
    return;
}

Since Perl has no types, the number will be treated as a string. Passing "500" is the same as passing 500.

say length 500;
say length "500";

__END__
3
3

The variable itself will not be converted. You don't need to care about that at all. Your code is fine, as long as you contain the number in a scalar reference.

The scalar reference doesn't care if it references a string or a number.

say length ${ \500 };
say length ${ \"500" };

__END__
3
3

Upvotes: 7

ikegami
ikegami

Reputation: 386331

If $value is a number as you claim, then ref will return an empty string, so execution will continue on to the next statement. You simply want

if (!ref($value) && length($value) >= 1000 ) {
    return;
}

This will take the length of the stringification of the $value, so length(500) is the same as length("500"), which is 3.


If $value is a reference to a number, your code is wrong too. length($value) will take the length of the stringification of the reference. You want

if (ref($ref) eq 'SCALAR' && length($$ref) >= 1000 ) {
    return;
}

$$ref (short for ${ $ref }) is the scalar to referenced by $ref.

(Note that it's very rare to have a reference to a scalar.)

Upvotes: 1

Related Questions