2

In the code below, we see that Dumper can tell whether a string variable (a variable for which the ref value is an empty string) is currently stored as numeric or as string. Is there any way, simpler than by using Dumper, to answer this question about a variable? Am I correct that a string variable contains perl magic which answers this question, if one could access this magic more directly?

#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper qw(Dumper);
my $var;
$var=55;
print ref $var; print Dumper $var;
$var='55';
print ref $var; print Dumper $var;

output:

$VAR1 = 55;
$VAR1 = '55';

Some of the reasons I want to understand this:

  1. I build HASHes and/or ARRAYs where the hash values or the array elements are four-digit years. The numbers come from various sources, sometimes from regex substitutions, sometimes from the command line, so they show up both as numeric and as string. But I want them all to line up exactly when I display them using Dumper.

  2. I am curious, which is ultimately why I write code in the first place.

  3. Somebody said that == is a more efficient check than eq, and I want to know exactly what kind of check I am implementing.

  4. There is a nifty way to force a string which looks like a number, to be stored as a number, as we see in How can I convert a string to a number in Perl?. See @Håkon Hægland 's comment. But I want to check or peek at a variable without changing it at all. Because I want to understand as clearly as possible what my code is doing, before it throws a warning or an error.

  5. As @Håkon Hægland pointed out, there is a meta::cpan module which may work, if installed. But it does not come standard with my perl: This is perl 5, version 18, subversion 4 (v5.18.4) built for darwin-thread-multi-2level and I want to write code that does not need enhancement at the system level. I want my scripts to run on any new macbook pro or linux machine that I eventually rsync my files to. My attempt to use Scalar::Type qw(is_*); throws Can't locate Scalar/Type.pm in @INC (you may need to install the Scalar::Type module). Is it really not possible to answer this question using "out of the box" perl?

Jacob Wegelin
  • 1,304
  • 11
  • 16
  • 2
    A variable might be stored as both. Why do you need it? – choroba Aug 01 '21 at 17:41
  • @ choroba, I edited the question to answer you – Jacob Wegelin Aug 01 '21 at 18:05
  • See also [How can I make Perl store integers as numbers instead of strings?](https://stackoverflow.com/q/56874215/2173773) – Håkon Hægland Aug 01 '21 at 18:23
  • See also [Scalar::Type](https://metacpan.org/pod/Scalar::Type) – Håkon Hægland Aug 01 '21 at 18:59
  • `==` works equally well on `55` and `"55"` without warnings. – choroba Aug 01 '21 at 19:07
  • 2
    Take al look at `B`'s `svref2obj->FLAGS`. As far as I can tell any of the flags `SVf_IOK | SVp_IOK | SVf_NOK | SVp_NOK` indicates a value in the numeric slot. – jo-37 Aug 01 '21 at 20:07
  • @jo-37 do you have a link for that? – Jacob Wegelin Aug 01 '21 at 20:52
  • 1
    Stackoverflow [How to tell apart numeric scalars and string scalars in Perl?](https://stackoverflow.com/questions/12686335/how-to-tell-apart-numeric-scalars-and-string-scalars-in-perl) – Polar Bear Aug 01 '21 at 21:36
  • Re "*The numbers come from various sources, sometimes from regex substitutions, sometimes from the command line, so they show up both as numeric and as string.*", Regex matches capture strings (since they match strings), and command-line arguments can only be strings. So **in all of your examples, they are stored as strings.** – ikegami Aug 02 '21 at 04:21
  • Re "*Somebody said that `==` is a more efficient check than `eq`*", This really doesn't make much sense. If you're comparing numbers, you want `==` **no matter if they are stored as a string or not**. If you aren't comparing numbers, you have to use `eq`. I neither situation does the the storage format used matter. – ikegami Aug 02 '21 at 04:24
  • Finally, what you are seeking to do is a really bad idea. Perl doesn't distinguish between numbers stored as signed integers, unsigned integers, floating point numbers and strings. If you start assigning meaning to these differences when Perl doesn't, **you WILL run into problems as a result.** – ikegami Aug 02 '21 at 04:24
  • I took the flags from `Scalar::Utils`'s `looks_like_number` implementation. See [ListUtil.xs](https://metacpan.org/release/PEVANS/Scalar-List-Utils-1.56/source/ListUtil.xs) – jo-37 Aug 02 '21 at 21:17

0 Answers0