Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a VSTRING from a scalar variable without using eval

I'm just curious, - is it even possible to create a v-string from a scalar variable without resorting to eval?

I. e., this works, but uses eval:

my $var = 'v1.2.3';
my $conversion = to_vstring_1($var);
# Prints "Version: 1.2.3, type: VSTRING"
printf("Version: %vd, type: %s\n", $conversion, ref \$conversion);

sub to_vstring_1 {
    my ($arg) = @_;

    $arg =~ tr/0-9.//cd;
    $arg = 'v' . $arg;

    return eval $arg;
}

These two variants also work, and do not use eval, but they print "SCALAR" instead of "VSTRING":

my $conversion_2 = to_vstring_2($var);
# Prints "Version: 1.2.3, type: SCALAR"
printf("Version: %vd, type: %s\n", $conversion_2, ref \$conversion_2);

my $conversion_3 = to_vstring_3($var);
# Prints "Version: 1.2.3, type: SCALAR"
printf("Version: %vd, type: %s\n", $conversion_3, ref \$conversion_3);

sub to_vstring_2 {
    my ($arg) = @_;

    $arg =~ tr/0-9.//cd;
    $arg = pack('U*', split(/\./, $arg));

    return $arg;
}

sub to_vstring_3 {
    my ($arg) = @_;

    $arg =~ tr/0-9.//cd;
    $arg =~ s/[._]?(\d+)/chr($1 & 0x0FFFF)/eg;

    return $arg;
}

So, is there a fourth way to do it?

like image 706
Basil Avatar asked Jul 12 '16 07:07

Basil


1 Answers

is it even possible to create a v-string from a scalar variable without resorting to eval?

Yes, it is, but it's a pain and there's no good reason to.

You can write XS code that:

  • parses your input string
  • converts the numbers to their char equivalents
  • assigns v-string magic to your scalar with a call to sv_magic

However, this is exactly what the internal function Perl_scan_vstring in toke.c does. Why reinvent the wheel?

like image 131
ThisSuitIsBlackNot Avatar answered Sep 19 '22 20:09

ThisSuitIsBlackNot