2

I'm trying to figure out how to use perl's eval to get a single element array. So far, I have:

use strict;
use warnings;
use Data::Dumper;

sub printit
{
    my $param = shift;
    my $thing = eval $param;
    if (ref($thing) =~ /HASH/ || ref($thing) =~ /ARRAY/) {
        print Dumper \$thing;
    } else {
        print $param . "\n";
    }
}
my $ip = "192.168.1.100";
my $ip_array = "[192.168.1.100]";
my $ip_array2 = "[192.168.1.100,]";
my $string = "{ a => 1, b => 2, c => 3}";
my $another_string = "[1, 2, 3 ]";

printit($ip);
printit($string);
printit($another_string);
printit($ip_array);
printit($ip_array2);

My output looks like:

[user]$ perl ~/tmp/cast.pl 
192.168.1.100
$VAR1 = \{
            'c' => 3,
            'a' => 1,
            'b' => 2
          };
$VAR1 = \[
            1,
            2,
            3
          ];
$VAR1 = \[
            "\x{c0}\x{a8}d"
          ];
$VAR1 = \[
            "\x{c0}\x{a8}d"
          ];

I think I'm getting a scalar ref for the last 2 print outs but I want an array with a single element like this:

$VAR1 = \[
            "192.168.1.100"
          ];
4
  • Are you sure that's what you're getting? I've just tried running your code, and got the desired output... Commented Apr 30, 2015 at 15:33
  • @Sobrique: What Perl version do you run? Commented Apr 30, 2015 at 15:33
  • Activeperl 5.20.1 - guessing we might have a quote interpolation thing going on here. Does: my $ip_array = "['192.168.1.100']"; show the same problems? Commented Apr 30, 2015 at 15:34
  • print Dumper \$thing; should be print Dumper $thing;. Use \ when you want to dump a variable that's not a scalar. Commented Apr 30, 2015 at 15:43

2 Answers 2

5

eval "[192.168.1.100]" is an array reference, not a scalar reference. The array reference contains one element, but it is not the string "192.168.1.100" as you might expect, because 192.168.1.100 is not quoted. Instead you are creating the version string 192.168.1.100.

The fix is to include a quote or quoting operator in your input.

my $ip_array = "['192.168.1.100']";
my $ip_array2 = "[qq/192.168.1.100/,]";

See "Version Strings" in perldata.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks @choroba for the edit -- I was having trouble finding the docs
Do you know if that's version specific? Because as noted - the OPs code works ok on my 5.20.2 perl. (Although granted, probably has other unintended consequences due to data typing)
@Sobrique, Look again. You are getting [ 192.168.1.100 ] instead of the desired [ "192.168.1.100" ]
True. So it's presumably same result, but handling the output a bit better.
[user]$ perl -v This is perl, v5.10.0 built for x86_64-linux-thread-multi
1

You say you want

[ "192.168.1.100" ]

but the code you pass to Perl is

[ 192.168.1.100 ]

Those are very different.

  • "192.168.1.100" creates the 13-character string 192.168.1.100.

  • 192.168.1.100 is short for v192.168.1.100, and it creates the same 4-character string as chr(192).chr(168).chr(1).chr(100).

One of many ways of writing what you want:

my $ip_array = '["192.168.1.100"]';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.