Parrot: Tutorial 3

Last modification: 2008/07/20 23:55

Tutorial 3: Perl Magic Cookies

What is a PMC?

PMC stands for "Parrot Magic Cookie". A PMC is an abstraction for any Perl data type: basic strings and ints, arrays, functions and even threads can all be created and tracked by a PMC.

There are a number of ways to create and use PMCs:

.sub pmctest new P0, .Integer # PMCs are one of the native register types in Parrot new $P0, .Integer # virtual registers work fine as well (this won't overwrite P0!) P0 = 100 $P0 = 200 .local Integer my_int # local variables work, but my_int = new Integer # remember you also have to declare them my_int = 300 my_int += P0 my_int += $P0 print my_int .end

As of Parrot 0.5.2, these are the currently registered PMC types:

1 Null 2 Env 3 Key 4 Random 5 UnManagedStruct
6 ManagedStruct 7 delegate 8 Compiler 9 Exception 10 Version
11 VtableCache 12 ParrotIO 13 ParrotLibrary 14 ParrotInterpreter 15 ParrotThread
16 LexPad 17 Timer 18 Pointer 19 Sub 20 Closure
21 Continuation 22 RetContinuation 23 Exception_Handler 24 Coroutine 25 Eval
26 NCI 27 Float 28 Integer 29 BigInt 30 Complex
31 String 32 Boolean 33 Ref 34 SharedRef 35 Array
36 FixedIntegerArray 37 IntList 38 Iterator 39 SArray 40 FixedStringArray
41 MultiArray 42 Hash 43 OrderedHash 44 TQueue 45 OS
46 File 47 AddrRegistry 48 Bound_NCI 49 Capture 50 Class
51 CodeString 52 deleg_pmc 53 Enumerate 54 EventHandler 55 Exporter
56 FixedBooleanArray 57 FixedFloatArray 58 FixedPMCArray 59 LexInfo 60 MultiSub
61 NameSpace 62 Object 63 Pair 64 ParrotRunningThread 65 PCCMETHOD_Test
66 PMCProxy 67 ResizableBooleanArray 68 ResizableFloatArray 69 ResizableIntegerArray 70 ResizablePMCArray
71 ResizableStringArray 72 Role 73 Scheduler 74 SchedulerMessage 75 Slice
76 STMLog 77 STMRef 78 STMVar 79 Super 80 Task
81 Undef

Whew! That's a lot of types. One basic PMC type is the Array. An example of its use is:

.sub use_array .local Array my_array my_array = new Array $I0 = my_array # get $I0 the size of my_array my_array = 4 # set the size of my_array to 4 my_array[0] = "a string" # store into the array at position 0 my_array[1] = 6 # is the value at position 1 defined? $I1 = defined my_array[1] if $I1 goto skip my_array[1] = 12 skip: $I2 = my_array[1] # get an integer value from the entry # at array position 1 .end

Some PMC types automatically populate themselves from external data when created. One example of this is the 'Env' type:

.sub print_env .local pmc e, i .local string key, val e = new Env i = new Iterator, e loop: unless i goto break key = shift i val = e[key] print key print ": " print val print "\n" goto loop break: .end

This example also handily demonstrates the Iterator type, which takes any PMC variable and allows it to be parsed one key at a time. We'll look at the Iterator type in more detail in a separate tutorial.

It is possible to inspect PMC variables to work out their type (typeof), and if they are a particular type of class (isa):

.sub m .local pmc var var = new Array $S0 = typeof var # returns 'Array' $I0 = typeof var # returns 35 - the PMC number for Array $I0 = 42 # PMC number for 'Hash' $I1 = valid_type $I0 unless $I1 goto skip $P0 = new $I0 $S0 = typeof $P0 print $S0 print " is a valid type\n" skip: $I1 = isa $P0, "Hash" unless $I1 goto skip2 print "$P0 is a Hash" skip2: .end