Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

understanding my() and typeglobs

by Ctrl-z (Friar)
on Mar 16, 2003 at 12:36 UTC ( [id://243462]=perlmeditation: print w/replies, xml ) Need Help??

pre-ramble:
Ive recently become quite enamoured with the idea of using anonymous typeglobs as the underlying datastructure for objects.
While the only real-world use I have seen of this is in the IO::* suite - I have came across several scenarios where having each of Perl's datatypes fits quite nicely with the problem space at hand. As a quick example

package nodeOfSomeKind; sub new { my $node = { refToParent => undef, hashParams => {}, arrayOfKids => [], }; return bless $node; }
now, wanting that structure to be tied to a socket/pipe/file is not wholly unlikely - but regardless, a typeglob fits perfectly.
When I create an anonymous typeglob - it looks something like this (courtesy Symbol.pm)

package Globject; our %classes; sub new { my $class = shift; # keep it unique my $symbolname = $class . ++$classes{$class}; my $tGlob = \*{$symbolname}; delete $Globject::{$symbolname}; # kill the package global return bless($tGlob, $class); }

so, deleting the autovivified symbol table entry gets rid of the package global - but the symbol lives on in the blessed reference. Woah!

So this got my tiny mind whirring...

From the little I know, lexical variables dont get symbol table entries as they exist only on a "pad" - for the scope of whatever block they exist in. Fine. But within that block, are they still represented in the equivalent of a local temporary symbol?. That is, wherever Perl is keeping tabs on all my variables for this scope, does it model the same structure as the symbol table?

sub foo { my ($foo, @foo, %foo); # now, within this lexical scope, are these names related return $foo; }

I guess my question/meditation would be twofold -
(i) apart from the lexical bit, what does my() do (if anything) that is different from Perl's normal way of creating variables?
(ii) blessed GLOB refs. Yay or Neigh?




time was, I could move my arms like a bird and...

Replies are listed 'Best First'.
Re: understanding my() and typeglobs
by Aristotle (Chancellor) on Mar 16, 2003 at 14:37 UTC
    1. Variables on the pad are not related. A package global $foo and @foo would be synonyms for ${*foo{SCALAR}} and @{*foo{ARRAY}}. On the pad, there's no glob; there's just a scalar referenced by the name $foo (including sigil) and an array referenced by the name @foo (again including sigil).

    2. Whatever floats your boat. If they're the most natural representation - go for it.

    Btw, why copypaste code from Symbol rather than use the module itself?

    Update/disclaimer: I may be wrong with respect to how the pad works, though the information given is to the best of my knowledg. In the interests of accuracy, following my posting this, I went to research whether this was all really correct. So far I come back empty handed. My fiddling with PadWalker supports the knowledge purported above, but that may not necessarily mean anything. If I'm wrong, please do correct me.

    Makeshifts last the longest.

      thanks. the emphasis on "including sigil" seems intriguing...

      btw, the tradeoff of a couple of keystrokes, for understanding a concept and controlling how it is implemented is worth the effort, IMHO. And in the context of a post related to symbols and lexicals, return bless gensym leaves a lot implied to the reader.


      time was, I could move my arms like a bird and...
Re: understanding my() and typeglobs (perl6)
by tye (Sage) on Mar 17, 2003 at 02:14 UTC

    I vaguely recall hearing that symbol tables in Perl 6 won't be composed of typeglobs. That would support my impression that typeglobs are rather perl4-ish; typeglobs were one way to get references back when we didn't have real references.

    Even if Perl6 doesn't use typeglobs for symbol tables (nor for file handles, if we are the least bit lucky), it might still support them just for backward compatability. But, personally, I wouldn't get used to them.

                    - tye

      Nope, no typeglobs in Perl 6, not even for filehandles. Like pad variables in Perl 5, the sigil is part of the name in Perl 6.

      Typeglobs are definitely dead in perl 6, and won't be available at all to your programs. Parrot will still be able to do globby things so we can make perl 5 code work under parrot, but it'll definitely be a workaround sort of thing.

      If you've (the generic you here, as I have no doubt tye knows how to make globs dance) never used them, this probably isn't a good time to start, as there's very rarely any good reason to do so in perl 5. If you knew when and where it was a good idea, you'd already be more than capable of doing it without asking how globs work. :)

        a fair point. Perl6 losing globs makes sense, but will there still be the equivalent of the symbol table - that can be read and manipulated at runtime?


        time was, I could move my arms like a bird and...
      Is this lexical-including-sigil documented anywhere?. The pod for my() and perlsub dont give much away.

      I was aware typeglobs were on the way out, and I agree this is probably a good thing - but in perl5, i think knowing how to apply this technique can be useful where handles and data need to be kept together.
      I was actually hoping some monks offer other scenarios they use GLOB refs for, but it appears to be my own little fetish :D.

      Sofar, I have found the biggest learning/usage payoff is with socket servers. Using the array part of the servers GLOB ref to pool connections - like the IO::Select array, but a nicer abstraction than the cargo-cultish IO::Select docs example.

      thanks again all
      and if you too share a GLOB ref fetish, call 0800-GLOBREF-SICK today!


      time was, I could move my arms like a bird and...

        Try this out. You'll note that the lexical's name is directly stored as '%method'. This isn't documented since you have to reach into the guts to get a lexical's name back out again so unless you're doing something really, highly unusual it doesn't show up.

        =pod Sample output ... Names no name '%methods' no name Values B::AV=SCALAR(0x8cb00) B::HV=SCALAR(0x8cb18) B::NULL=SCALAR(0x8cb30) =cut use strict; use warnings; no warnings 'uninitialized'; use constant DEBUG => 1; use B; { # Get my new really private object where even # the methods are hidden my $object = new object; # and now violate it. Privacy? Ha! my $c_hash = extractLexHash( $object ); while (my ($key, $val) = each %$c_hash ) { print "$key\t@$val\n"; } } sub extractLexHash { my $Obj = B::svref_2object($_[0]); my ($LexicalNames, $LexicalValues) = map { [ $_->ARRAY ] } $Obj->PADLIST->ARRAY; # for a cheap thrill print the contents of # $LexicalNames if (DEBUG) { print "Names\n"; print "@{[$_->can('PV') ? \"'\".$_->PV().\"'\" : 'no name']}\n +" for @$LexicalNames; print "Values\n"; print "$_\n" for @$LexicalValues; exit; } my %Lexicals = (); for my $index (0 .. # min(@LexicalNames, @LexicalValues) (@$LexicalNames < @$LexicalValues ? @$LexicalNames : @$Lexica +lValues)) { next unless B::class($LexicalNames->[$index]) eq 'PVNV'; my @values = $LexicalValues -> [$index] -> ARRAY; while (@values) { my $LexicalName = shift @values; my $LexicalObj = shift @values; $Lexicals{$LexicalName} = [ $LexicalName, bless(B::svref_2object(\$Lexic +alName),'B::IV')->IVX, $LexicalObj->RV ]; } } return \%Lexicals; } package object; sub new { my %methods; %methods = ( me => sub { print "me!\n" }, you => sub { print "you!\n" } ); bless sub { $methods{me}->() }, 'object'; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://243462]
Approved by Tomte
Front-paged by mattriff
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-03-29 10:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found