in reply to Distinguishing a v-string from something else

Taint neccessarly so. My IP address, for example, is 68.83.61.190. (Actualy, it isn't; I fudged the numbers both so I wouldn't get cracked and so it'd work.) Also, adding a trailing .0 /will/ effect the string, and may or may not effect the meaning. There is /no/ general way to tell a v-string from somthing else. For example, if you get '1.0', that could have really been written '1.0', or 49.46.48. There's no way to tell, other then context.

Sorry.


Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

  • Comment on Re: Distinguishing a v-string from something else

Replies are listed 'Best First'.
Re: Re: Distinguishing a v-string from something else
by John M. Dlugosz (Monsignor) on Dec 05, 2002 at 04:34 UTC
    Good point. My context is that of a version number. Adding trailing zeros will not affect the ordering of greater/less, but will affect exact matches using eq (I figured stripping trailing zeros to normalize before comparing for equality).

    A function that takes an IP address as a buffer of 4 bytes, a v-string (which will UTF-8-encode the values above 127), or a string can tell the difference by looking for the presence of only digits and dots and of the total length.

    —John

      a v-string (which will UTF-8-encode the values above 127)

      actually, they're UTF-8 encoded if they're above 255.

      > perl -MDevel::Peek -e"$a=v256;$b=v128;Dump$a;Dump$b" SV = PV(0x182ebf4) at 0x182383c REFCNT = 1 FLAGS = (POK,pPOK,UTF8) PV = 0x182013c "\304\200"\0 CUR = 2 LEN = 3 SV = PV(0x182ec24) at 0x1823848 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x182012c "\200"\0 CUR = 1 LEN = 2

      you can differentiate between a number and a v-string by examining the result of the SvPOKp(SV*) macro. a true return means a v-string, false indicates a number.

      if you can differentiate between a v-string and any other string by your above method, you should be able to determine whether or not you have a v-string, no?

      ~Particle *accelerates*

        Re: actually, they're UTF-8 encoded if they're above 255.

        I just got around to verifying this. Actually, it does not work the same as chr, in that the v-string encoding faithfully follows the utf8 pragma, while chr decides for itself whether to return a byte or char oriented string regardless of the pragma setting.

        I'm wondering, though, if a number without a v and only 1 dot (normally a floating-point numeric constant) is dual-valued magic when parsed as the indirect object of a use or require? Have to peek at what comes into VERSION.

        if you can differentiate between a v-string and any other string by your above method, you should be able to determine whether or not you have a v-string, no?

        I can easily enough decide if I have a v-string or a string of the form "1.2.3.4" as ASCII, provided it has at least one dot in the latter. That's my purpose: to allow either as the value of $VERSION.

        —John

Re^2: Distinguishing a v-string from something else
by particle (Vicar) on Dec 05, 2002 at 14:36 UTC
    For example, if you get '1.0', that could have really been written '1.0', or 49.46.48. There's no way to tell, other then context.

    i'm not so sure this is correct. the code below seems to illustrate the storage of v-strings is different than other text strings, as v-strings are stored as octals and periods are not included. \1 is not the same as chr(49).

    > perl -MDevel::Peek -e"$a=v1.0; $b='1.0'; Dump$a; Dump$b" SV = PV(0x182ebf4) at 0x182383c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x182013c "\1\0"\0 CUR = 2 LEN = 3 SV = PV(0x182ec24) at 0x1823848 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x182012c "1.0"\0 CUR = 3 LEN = 4

    ~Particle *accelerates*

      Ahh, but I didn't say that v1.0 eq "1.0"; I said '1.0' eq 49.46.48, and they are:

      >perl -MDevel::Peek=Dump -e "$a=49.46.48; $b='1.0'; Dump $a; Dump $b" SV = PV(0x225484) at 0x19245fc REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x22ce4c "1.0"\0 CUR = 3 LEN = 4 SV = PV(0x2254b4) at 0x1924608 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x22b424 "1.0"\0 CUR = 3 LEN = 4

      Oh, two BTWs: all strings are stored as an array of chars (c-style); base doesn't enter into it, in the same way as 0x10 and 16 are both the same number. It's just that Devel::Peek prints nonprintable characters as octal escapes.


      Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).