Note: All variables used or mentioned here are package global variables, not lexicals.
*foo is a typeglob. Using it, you can access @foo, $foo, %foo and &foo. You probably know that. You can get a reference to @foo by using \@foo, but also by using *foo{ARRAY}.
\$foo == *foo{SCALAR} \@foo == *foo{ARRAY} \%foo == *foo{HASH} \&foo == *foo{CODE} \*foo == *foo{GLOB} *foo{IO}
So far, so good. If you want to throw away our old global variable and replace it with another, you assign a reference to *foo. Perl will use the appropriate slot, *foo{THING} itself is read only.
*foo = \"Scalar" # Note: constants are read-only *foo = [ 'Array' ] *foo = { foo => 'Hash' } *foo = sub { print 'Subroutine' } *foo = Symbol::gensym # GLOB *foo = Symbol::geniosym # IO
References are being assigned. Nothing special. Note that no data is copied. If you have $foo, that is a reference to an array, and assign it to *foo, both @$foo and @foo are the same array. And $foo and \@foo are references to that array.
References can be blessed. And because the slots in a typeglob are references, they can be blessed too. Just like you would bless anything else. And because if you reference something that is dereferenced, you get the same reference you dereferenced, the reference would still blessed, if it was originally.
sub method { print "\@_ is: @_\n" } *foo = bless [ 'Array' ], 'main'; *foo{ARRAY}->method("It's an object now");
As you can see, no scalar variable is needed to store an object in. You can use the slots of a typeglob as well. Remember how \@foo == *foo{ARRAY}? This means \@foo can be an object!
sub method { print "\@_ is: @_\n" } *foo = bless [ 'Array' ], 'main'; (\@foo)->method("It's an object now");
The parens are needed because \ has lower precedence than ->.
Perhaps you think this is nice and all, and think you will never use objects that aren't stored in normal scalar variables. Well, think again. File and directory handles, found in the IO slot, are blessed references. That's right, filehandles are objects. Blessed to IO::Handle. Even if you're not using that module.
use IO::Handle; STDOUT->autoflush(1);
What's going on here, why doesn't Perl look for an autoflush method in a class named STDOUT? *STDOUT{IO} is a blessed IO reference. When a string is used in an OO manner (the left hand side of the arrow operator), it's used as a filehandle if the IO slot is used. If it there's no IO slot, the bareword is supposed to be a class.
With foo->method(), IO::Handle::method is used if foo is a filehandle, but foo::method is used if it is not. "foo"->method() is no different. Consider the following code:
use IO::Handle; use CGI; open CGI, 'somefile' or die $!; my $cgi = CGI->new;
What is $cgi here? Is it a CGI object, as the guy I was helping expected? No. Is it an IO::Handle object, as I expected? No. It is a GLOB reference, blessed to GLOB. I'd like to know why, because even *CGI{IO}->new would have returned an IO::Handle. Can anyone explain please what happens in CGI->new here?
Things I learned so far:
- ref(\@foo) doesn't have to be ARRAY
- Filehandles are objects, even if IO::Handle isn't loaded yet (i.e. they are objects without methods)
- Once some string is used as a file handle, you can no longer use it as a class name with the arrow operator
- *foo{FILEHANDLE} is a synonym for *foo{IO}, to be backwards compatible
- Even though *foo{FILEHANDLE} is a synonym for *foo{IO}, they return a different reference
- You can use other classes than IO::Handle for filehandle objects. Simply re-bless.
- I need sleep. Good night everyone.
- Yes, I reinvent wheels.
- Spam: Visit eurotraQ.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: When CGI->new doesn't return a CGI object
by grinder (Bishop) on Jan 07, 2003 at 08:29 UTC | |
Re: When CGI->new doesn't return a CGI object
by adrianh (Chancellor) on Jan 07, 2003 at 17:28 UTC | |
by demerphq (Chancellor) on Jan 07, 2003 at 21:33 UTC |