Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Getting to variables contained in a typeglob referenced by a scalar.

Reply
Thread Tools

Getting to variables contained in a typeglob referenced by a scalar.

 
 
Jaap Karssenberg
Guest
Posts: n/a
 
      06-30-2004
The point is the nature of a typeglob, this entity is a namespace node
which refers to _any_ type with that name (hence "typeglob"). So you can
regard a typeglob reference as a reference to any type at the same time.

Using ->{SCALAR} is just a special syntax to force dereferencing as a
scalar type. Using $$fh does this implicitly.

--
) ( Jaap Karssenberg || Pardus [Larus] | |0| |
: : http://pardus-larus.student.utwente.nl/~pardus | | |0|
) \ / ( |0|0|0|
",.*'*.," Proud owner of "Perl6 Essentials" 1st edition wannabe
 
Reply With Quote
 
 
 
 
ddtl
Guest
Posts: n/a
 
      06-30-2004

Hello,

After 'open' is called in the following way:

open my $fh, $file;

'$fh' contains a reference to a filehandle, i.e., somewhere in the 'open'
function there is probably a following assignment:

$fh = \*SOME_TYPEGLOB;

(and somehow that typeglob is anonymous (?), so the filehandle is
also anonymous).

If I understand correctly, it actually means that '$fh' contains
a reference to a typeglob, because wherever there is a filehandle,
it can be substituted for a typeglob.

Than, if we want to get to the variables inside that typeglob, we
have to do it in the following way:

*$fh - access the fileglob
*$fh->{SCALAR} - access a reference to a scalar (typeglob is also a special
hash)
${*$fh->{SCALAR}} - access the scalar itself.

But "Programming Perl" (14.4.1) mentions another, easier way -
just use $$$fh (or @$$fh or %$$fh, etc.).

I don't understand, though, how it works - what do we access when
$$fh is used - there is no scalar reference inside '$fh'?
The book doesn't mention it as some new way of using typeglobs/references,
which probably means that it should be clear from the previous chapters
why and how it works, and it seems that I missed the point.


The question is, then: how and why $$$fh etc. work, and where is an
explanation for it in the book (or just in the documentation)


ddtl.
 
Reply With Quote
 
 
 
 
ddtl
Guest
Posts: n/a
 
      06-30-2004
On Wed, 30 Jun 2004 19:28:59 +0200, Jaap Karssenberg
<(E-Mail Removed)> wrote:

>The point is the nature of a typeglob, this entity is a namespace node
>which refers to _any_ type with that name (hence "typeglob"). So you can
>regard a typeglob reference as a reference to any type at the same time.
>
>Using ->{SCALAR} is just a special syntax to force dereferencing as a
>scalar type. Using $$fh does this implicitly.


But if reference to a typeglob is equivalent to a reference to whatever type
with that name I want, it should be able to say:

$$fh = 10;
print "$$fh";

and it would print out "10", because '$fh contains a reference to a
typeglobe == a reference to a scalar (among other things), so
dereferencing '$fh' should get to the value, but the above prints:

*main::10

so it means that another level of indirection is needed, i.e. - '$fh' does not
contains a reference to a scalar (or it's equivalent)?

ddtl.
 
Reply With Quote
 
ddtl
Guest
Posts: n/a
 
      06-30-2004

>> $$fh = 10;
>> print "$$fh";

>
>$fh = 10;
>$ref_fh = \$fh;
>print $$ref_fh;
>


'$fh' already contains a typeglob reference (put there by a 'open' function),
see my first post in the thread - I am continuing the discussion.
(all the point is when a scalar contains a typeglob reference,
not a usual reference to a scalar).

ddtl.
 
Reply With Quote
 
Steven Kuo
Guest
Posts: n/a
 
      06-30-2004
On Wed, 30 Jun 2004, ddtl wrote:

>
> Hello,
>
> After 'open' is called in the following way:
>
> open my $fh, $file;
>
> '$fh' contains a reference to a filehandle, i.e., somewhere in the 'open'
> function there is probably a following assignment:
>
> $fh = \*SOME_TYPEGLOB;
>
> (and somehow that typeglob is anonymous (?), so the filehandle is
> also anonymous).
>
> If I understand correctly, it actually means that '$fh' contains
> a reference to a typeglob, because wherever there is a filehandle,
> it can be substituted for a typeglob.
>
> Than, if we want to get to the variables inside that typeglob, we
> have to do it in the following way:
>
> *$fh - access the fileglob
> *$fh->{SCALAR} - access a reference to a scalar (typeglob is also a special
> hash)
> ${*$fh->{SCALAR}} - access the scalar itself.
>
> But "Programming Perl" (14.4.1) mentions another, easier way -
> just use $$$fh (or @$$fh or %$$fh, etc.).
>
> I don't understand, though, how it works - what do we access when
> $$fh is used - there is no scalar reference inside '$fh'?
> The book doesn't mention it as some new way of using typeglobs/references,
> which probably means that it should be clear from the previous chapters
> why and how it works, and it seems that I missed the point.




$fh is a reference to a GLOB
$$fh is the GLOB itself
$$$fh is the SCALAR inside the GLOB



> The question is, then: how and why $$$fh etc. work, and where is an
> explanation for it in the book (or just in the documentation)



Perhaps this makes it clearer:

use strict;
use warnings;
use Scalar::Util;
use Symbol;

$\ = $/;

my $foo = gensym;
$$$foo = 'bar';

open ($foo, '<', '/etc/services')
or die "Could not open file : $!";

if ( fileno($foo)
and fileno($foo) == fileno(*$foo{IO}) ) {
print "SAME FILE DESCRIPTOR\n";
}

print $$$foo;

# equivalently

print ${*$foo{SCALAR}};

print Scalar::Util::reftype($foo), "\n";

--
Hope this helps,
Steven

 
Reply With Quote
 
ddtl
Guest
Posts: n/a
 
      06-30-2004

>That's fine. However, your displayed code is
>trying to set a value for a referenced variable.
>Your displayed code makes no reference to your
>already set $fh variable.
>
>If you did actually reference your $fh variable,
>
>$fh = 10;
>$$fh = 10;
>print $$fh;
>
>Modification of a read-only value attempted at test.pl line 4.


I don't really understand what do you mean. Here is a complete
listing of a test program:

---------------------------------------------
use strict;

open (my $fh, "C:\\a\\projects\\tests\\a.pl") or
die "Cannot open file: $!\n";
$$fh = 10;
print "$$fh\n";
---------------------------------------------

When i run that script, it prints:
---------------------------------------------
*main::10
---------------------------------------------

The reference contained in $fh was put there by a 'open' function
(there is an autovivification going on), the reference is to an
anonymous variable (typeglob, actually). Then begins a question
itself (see previous posts).

So there is no attempt to set a read-only value...

ddtl.

 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      06-30-2004
ddtl <this.is@invalid> wrote in comp.lang.perl.misc:
>
> Hello,
>
> After 'open' is called in the following way:
>
> open my $fh, $file;
>
> '$fh' contains a reference to a filehandle, i.e., somewhere in the 'open'
> function there is probably a following assignment:
>
> $fh = \*SOME_TYPEGLOB;
>
> (and somehow that typeglob is anonymous (?), so the filehandle is
> also anonymous).


The module Symbol creates anonymous globs. It is used in the creation
of this kind of file handle.

> If I understand correctly, it actually means that '$fh' contains
> a reference to a typeglob, because wherever there is a filehandle,
> it can be substituted for a typeglob.


I think you mean "...substituted *by* a typeglob".

> Than, if we want to get to the variables inside that typeglob, we
> have to do it in the following way:
>
> *$fh - access the fileglob
> *$fh->{SCALAR} - access a reference to a scalar (typeglob is also a special
> hash)
> ${*$fh->{SCALAR}} - access the scalar itself.
>
> But "Programming Perl" (14.4.1) mentions another, easier way -
> just use $$$fh (or @$$fh or %$$fh, etc.).
>
> I don't understand, though, how it works - what do we access when
> $$fh is used - there is no scalar reference inside '$fh'?


It's the glob. You need older books (Perl 4 level) to find any that talk
about (type-)globs at any length. Their original purpose has entirely
been superseded by references.

> The book doesn't mention it as some new way of using typeglobs/references,
> which probably means that it should be clear from the previous chapters
> why and how it works, and it seems that I missed the point.
>
>
> The question is, then: how and why $$$fh etc. work, and where is an
> explanation for it in the book (or just in the documentation)


The fact that $fh is created as a file handle is irrelevant, it's just
a behavior of globs. To see how globs work, observe this:

our ( $var, @var, %var);
$var = 123;
%var = ( aaa => 123, bbb => 456 );
@var = qw( boo hoo woo);

my $glob = *var;

print "$$glob\n";
print "@$glob\n";
print "$_=>$$glob{ $_} " for keys %$glob; print "\n";

....which prints

123
boo hoo woo
bbb=>456 aaa=>123

So $glob behaves like a universal reference in that can be de-referenced
as a scalar, an array, a hash, and a sub (not shown).

Adding a level of (ordinary) reference works just as it should, and
results in the same output:

my $fh = \ $glob; # same as $fh = \ *var;

print $$$fh, "\n";
print "@$$fh\n";
print "$_=>$$$fh{ $_} " for keys %$$fh; print "\n";

Anno
 
Reply With Quote
 
Richard Morse
Guest
Posts: n/a
 
      06-30-2004
In article <(E-Mail Removed)>,
ddtl <this.is@invalid> wrote:

> You are not supposed to use close() on indirect filehandles - in order
> to close the file you either exit the scope, or use:


I'm sorry, but I don't see this in `perldoc perlopentut`, `perldoc -f
open`, or `perldoc -f close`.

I do see that you _may_ just let them be automatically closed on exiting
the surrounding scope. But nothing that forbids using close on them --
in fact, `perldoc -f close` states:

: FILEHANDLE may be an expression whose value can be used as an
: indirect filehandle, usually the real filehandle name.

And in the Camel book (version 3) it says:

: FILEHANDLE may be an expression whose value can be used as an
: indirect filehandle (either the real filehandle name or a
: reference to anything that can be interpreted as a filehandle
: object).

Where do you find that you are not supposed to close files?

Ricky
 
Reply With Quote
 
ddtl
Guest
Posts: n/a
 
      06-30-2004

>> When i run that script, it prints:

>
>> *main::10

>
>
>Doesn't print anything on my system, Perl 5.6 version.


Checked both under Windows & under Linux (though I had to change
the path for a Linux version - everything else was left unchanged),
in both cases the output was "*main::10". I use Perl 5.8.4 on all
systems.

>You really don't want to do that.


It was just an example, so that I would be able to ask a question.

>Add this,
>
>close ($fh) || die "$!";
>
>You will learn why.


You are not supposed to use close() on indirect filehandles - in order
to close the file you either exit the scope, or use:

undef $f;

That is why you get an error, see perlopentut.

>Use of strict is really not needed for a three line script
>but is optional. Use it if you really need strict.


I use strict even for one-liners - this is a personal preference, and
it is certainly not wrong.

>Use of a "my" lexical declaration for a global serves no purpose
>just as use of a "our" declaration for globals, serves no purpose.


This is just an *example*. BTW, you could not use "my" for global -
becaise if variable is declared with "my", it is not a global.

ddtl.
 
Reply With Quote
 
Steven Kuo
Guest
Posts: n/a
 
      06-30-2004
On Thu, 1 Jul 2004, ddtl wrote:

>
> >$fh is a reference to a GLOB
> >$$fh is the GLOB itself
> >$$$fh is the SCALAR inside the GLOB
> >

>
> But how do you get to the typeglob using a funny character used to
> access scalars - glob is not scalar. I could understand why it works if
> instead of '$' it had been possible to use other funny characters as
> well, like '@$fh' or '%$fh' - then i would infer: because glob contains
> everything, you can get to glob by dereferencing glob reference with
> any funny character, but in fact only '$$f' gets you a glob, all the other
> constructs generate an error. Then why it works?
>



If you want the array and hash in the GLOB, then you write:
@$$fh and %$$fh respectively (not @$fh and not %$fh);

It 'works' because the deference syntax is unambiguous. From

'perldoc perlref'

....

A typeglob may be dereferenced the same way a reference can, because
the dereference syntax always indicates the type of reference desired.
So "${*foo}" and "${\$foo}" both indicate the same scalar variable.


--
Hope this helps,
Steven

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
handling of regexp objects that aren't referenced by variables,arrays, tables or objects ThomasW Ruby 11 09-28-2009 01:52 AM
Getting unable to cast error (when same object is referenced in client and web service) Rahul ASP .Net 5 03-01-2008 11:13 PM
Why am I getting a compile error on a referenced Web Service parameter Ray Stevens ASP .Net Web Services 5 02-04-2006 06:12 PM
Typeglob Qs kj Perl Misc 2 06-28-2005 05:51 AM
Importing from a file to use contained variables Jeff Wagner Python 11 11-30-2003 07:19 AM



Advertisments