Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

breaking open a scalar with unpack P

by patcat88 (Deacon)
on Dec 22, 2010 at 23:12 UTC ( #878687=perlquestion: print w/replies, xml ) Need Help??

patcat88 has asked for the wisdom of the Perl Monks concerning the following question:

How kosher is the following code? Is it acceptable to break open a scalar like this? is this documented in Perl's documentation? how often is this done? Does printing of references to scalars always produce SCALAR(0XBABABABA)? is that documented? is a reference being a dualvar documented?

I was looking at the source code of Acme::ESP and I saw the module breaking open a scalar. The rest of the code I can't figure out due to a lack of parenthesis.

I wrote this script the test out if Acme::ESP was really breaking open the scalars or not.

I am aware this is not 64 compliant, although using 'J' in the right places should fix that.

$c = 'camel'; $ref =\$c; print (($ref+0)."\n"); $ptr = pack( "L", $ref); @a = unpack('LLLL',unpack('P16',$ptr)); $flags = $a[2]; $h{'SVf_IOK'} = 0x00000100; # has valid public integer value */ $h{'SVf_NOK'} = 0x00000200; # has valid public numeric value */ $h{'SVf_POK'} = 0x00000400; # has valid public pointer value */ $h{'SVf_ROK'} = 0x00000800; # has a valid reference pointer */ $h{'SVp_IOK'} = 0x00001000; # has valid non-public integer value */ $h{'SVp_NOK'} = 0x00002000; # has valid non-public numeric value */ $h{'SVp_POK'} = 0x00004000; # has valid non-public pointer value */ $h{'SVp_SCREAM'} = 0x00008000; # has been studied? */ $h{'SVphv_CLONEABLE'} = 0x00008000; # PVHV (stashes) clone its objec +ts */ $h{'SVpgv_GP'} = 0x00008000; # GV has a valid GP */ $h{'SVprv_PCS_IMPORTED'} = 0x00008000; # RV is a proxy for a constan +t #subroutine in another package. Set the #CvIMPORTED_CV_ON() if it needs to be #expanded to a real GV */ $h{'SVs_PADSTALE'} = 0x00010000; # lexical has gone out of scope */ $h{'SVpad_STATE'} = 0x00010000; # pad name is a "state" var */ $h{'SVs_PADTMP'} = 0x00020000; # in use as tmp */ $h{'SVpad_TYPED'} = 0x00020000; # pad name is a Typed Lexical */ $h{'SVs_PADMY'} = 0x00040000; # in use a "my" variable */ $h{'SVpad_OUR'} = 0x00040000; # pad name is "our" instead of "my" */ $h{'SVs_TEMP'} = 0x00080000; # string is stealable? */ $h{'SVs_OBJECT'} = 0x00100000; # is "blessed" */ $h{'SVs_GMG'} = 0x00200000; # has magical get method */ $h{'SVs_SMG'} = 0x00400000; # has magical set method */ $h{'SVs_RMG'} = 0x00800000; # has random magical methods */ $h{'SVf_FAKE'} = 0x01000000; # 0: glob or lexical is just a copy #1: SV head arena wasn't malloc()ed #2: in conjunction with SVf_READONLY #marks a shared hash key scalar #(SvLEN == 0) or a copy on write #string (SvLEN != 0) [SvIsCOW(sv)] #3: For PVCV, whether CvUNIQUE(cv) # refers to an eval or once only # [CvEVAL(cv), CvSPECIAL(cv)] # 4: Whether the regexp pointer is in # fact an offset [SvREPADTMP(sv)] # 5: On a pad name SV, that slot in the # frame AV is a REFCNT'ed reference # to a lexical from "outside". */ $h{'SVphv_REHASH'} = 0x01000000; # 6: On a PVHV, hash values are b +eing #recalculated */ $h{'SVf_OOK'} = 0x02000000; # has valid offset value. For a PVHV thi +s #means that a hv_aux struct is present #after the main array */ $h{'SVf_BREAK'} = 0x04000000; # refcnt is artificially low - used by #SV's in final arena cleanup */ $h{'SVf_READONLY'} = 0x08000000; # may not be modified */ foreach(keys %h) { print "matched $_\n" if ($flags & $h{$_}); } print 'string depointered "'.unpack('P6',pack('L',$a[3])).'"'."\n";

Replies are listed 'Best First'.
Re: breaking open a scalar with unpack P
by ikegami (Patriarch) on Dec 22, 2010 at 23:34 UTC

    How kosher is the following code? Is it acceptable to break open a scalar like this?

    It's subject to breakage between Perl versions. Why not use B? Or if your just need a debugging or learning tool, I use Devel::Peek often.

    The last line is wrong, since it relies on the scalar being a certain kind of scalar.

    is this documented in Perl's documentation?

    Which "this"? Outside of the perl distro, there's illguts. One normally uses the macros and constants Perl provides in C, so one doesn't normally need to know the exact values.

    Does printing of references to scalars always produce SCALAR(0XBABABABA)?


    $ perl -E'{ package Bar; use overload q{""} => sub { "Ha!" }; } say bless(\my $foo, "Foo"); say bless(\my $bar, "Bar"); ' Foo=SCALAR(0x817bce8) Ha!

    References to unblessed scalars always stringify to that format.

    is a reference being a dualvar documented?

    I've never heard of dualvar references, much less seen one. You couldn't have an RV/IV or RV/UV dualvar as RV, IV and UV share the same field of a scalar, but it seems possible to create an RV/NV or RV/PV dualvar. No idea how Perl would handle that.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://878687]
Approved by ww
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2022-01-26 16:28 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (69 votes). Check out past polls.