Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > (quickie) (Aliasing) Possible to get this to work in strict?

Reply
Thread Tools

(quickie) (Aliasing) Possible to get this to work in strict?

 
 
Crom
Guest
Posts: n/a
 
      12-14-2004
1: my $n = 5;
2: *r = \$n;
3:
4: $r++; # both should now be 6
5: $n++; # both should not be 7
6:
7: print "\$n = $n\n\$r = $r";


Works fine without 'use strict'...

$n = 7
$r = 7

....but with strict it barfs.

Global symbol "$r" requires explicit package name at line 6.
Global symbol "$r" requires explicit package name at line 9.



 
Reply With Quote
 
 
 
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      12-14-2004
Also sprach Crom:

> 1: my $n = 5;
> 2: *r = \$n;
> 3:
> 4: $r++; # both should now be 6
> 5: $n++; # both should not be 7
> 6:
> 7: print "\$n = $n\n\$r = $r";
>
>
> Works fine without 'use strict'...
>
> $n = 7
> $r = 7
>
> ...but with strict it barfs.
>
> Global symbol "$r" requires explicit package name at line 6.
> Global symbol "$r" requires explicit package name at line 9.


You can circumvent that by pre-declaring $r using our() or 'use vars':

use strict;

our $r; # pre-5.6.0 perls: use vars qw/$r/;
my $n = 5;

*r = \$n;
$r++;
print "$n - $r\n";
__END__
6 - 6

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      12-14-2004
Crom <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> 1: my $n = 5;
> 2: *r = \$n;
> 3:
> 4: $r++; # both should now be 6
> 5: $n++; # both should not be 7
> 6:
> 7: print "\$n = $n\n\$r = $r";
>
>
> Works fine without 'use strict'...
>
> $n = 7
> $r = 7
>
> ...but with strict it barfs.
>
> Global symbol "$r" requires explicit package name at line 6.
> Global symbol "$r" requires explicit package name at line 9.


"use strict" means, among other things, that you have to declare
all variables. You haven't declared your variables, so it complains.

Anno
 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      12-15-2004
On Tue, 14 Dec 2004 09:54:16 +0100, "Tassilo v. Parseval"
<(E-Mail Removed)> wrote:

>You can circumvent that by pre-declaring $r using our() or 'use vars':
>
> use strict;
>
> our $r; # pre-5.6.0 perls: use vars qw/$r/;
> my $n = 5;
>
> *r = \$n;
> $r++;
> print "$n - $r\n";
> __END__
> 6 - 6


Speaking of which, may I ask you to give an explanation of how this
works internally? (Just curious...)

What I mean is that we all know that Perl5 has basically two
fundamentally orthogonal variable systems. And we know we can access
directly a package's symbol table, but AFAIK we can't do the same with
lexical variables, even though there "MUST" be one, and given the
orthogonality hinted to above, it is somewhat surprising that such an
aliasing can even be done. Oh, and of course on lexical scope exit it
will "downgrade" to a simple copy, won't it? (Just tried, and AFAICT
it is indeed so).

Incidentally Perl6's planned solution to the variables' nature
dichotomy by means of an inner layer of magic, namely that provided by
the MY package, IMHO is very appealing, and I wonder wether it may
eventually leak in some future Perl5 release...


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      12-16-2004
Also sprach Michele Dondi:

> On Tue, 14 Dec 2004 09:54:16 +0100, "Tassilo v. Parseval"
><(E-Mail Removed)> wrote:
>
>>You can circumvent that by pre-declaring $r using our() or 'use vars':
>>
>> use strict;
>>
>> our $r; # pre-5.6.0 perls: use vars qw/$r/;
>> my $n = 5;
>>
>> *r = \$n;
>> $r++;
>> print "$n - $r\n";
>> __END__
>> 6 - 6

>
> Speaking of which, may I ask you to give an explanation of how this
> works internally? (Just curious...)


It probably means that on the inside just the pointer to the original
variable is copied. On ordinary assignments, perl copies the C structure
into a new variable. Here it just copies the memory address.

> What I mean is that we all know that Perl5 has basically two
> fundamentally orthogonal variable systems. And we know we can access
> directly a package's symbol table, but AFAIK we can't do the same with
> lexical variables, even though there "MUST" be one, and given the
> orthogonality hinted to above, it is somewhat surprising that such an
> aliasing can even be done. Oh, and of course on lexical scope exit it
> will "downgrade" to a simple copy, won't it? (Just tried, and AFAICT
> it is indeed so).


No, an alias remains an alias. Perl increments the reference-count of
the variable to be aliased:

ethan@ethan:~$ perl -MDevel:eek
{ my $c = 42;
Dump($c);
*alias = \$c;
Dump($alias);
}
Dump($alias);
__END__
SV = IV(0x8163094) at 0x814cc6c
REFCNT = 1
FLAGS = (PADBUSY,PADMY,IOK,pIOK)
IV = 42
SV = IV(0x8163094) at 0x814cc6c
REFCNT = 2
FLAGS = (PADBUSY,PADMY,IOK,pIOK)
IV = 42
SV = IV(0x8163094) at 0x814cc6c
REFCNT = 1
FLAGS = (PADBUSY,PADMY,IOK,pIOK)
IV = 42

So after doing the aliasing, the reference-count has gone up to 2. On
scope exist, it is decreased again by one. Since the reference-count
hasn't yet gone to zero, the memory previously associated with 'my $c'
remains intact and can still be accessed through the alias. Also note
how the memory addresses involved are all identical. My suspicion is
that aliases were just a side-effect that turned out to be very useful.
It is the C-semantics of copying a pointer ported to perl.

Aliases are a lot like hard links on Unices. You can delete the file
that was hard-linked to but the hard link itself remains valid and
behaves if it was the original file. Which it is anyway, from the point
of view of the filesystem.

As for lexical variables, technically they are not very different from
package variables. They have the PADMY flag set which means they are
subject to refcounting. Other than that, they only differ from package
variables in that they are not kept in a symbol-table but in so called
pads. Each block has its own pad and they are inaccessible from
pure-Perl (unless someone writes an XS extension that makes them
accessible).

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
Arndt Jonasson
Guest
Posts: n/a
 
      12-16-2004

"Tassilo v. Parseval" <(E-Mail Removed)> writes:
> As for lexical variables, technically they are not very different from
> package variables. They have the PADMY flag set which means they are
> subject to refcounting. Other than that, they only differ from package
> variables in that they are not kept in a symbol-table but in so called
> pads. Each block has its own pad and they are inaccessible from
> pure-Perl (unless someone writes an XS extension that makes them
> accessible).


Maybe I misunderstand the above, but it seems to say that in the code
snippet below, the lexical variable $x should not be seen by the
'eval' inside the block. But the output in the block is "r = 7" (while
$y is 5, showing that the outer $x is unchanged), so 'eval' does see
the lexical variable. What am I missing?

$e = '$x';
$x = 5;
*y = $x;
{
my $x = 7;
$r = eval $e;
print "r = $r\n";
print "outer r = $y\n";
}
$r = eval $e;
print "r = $r\n";
 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      12-16-2004
Also sprach Arndt Jonasson:

> "Tassilo v. Parseval" <(E-Mail Removed)> writes:
>> As for lexical variables, technically they are not very different from
>> package variables. They have the PADMY flag set which means they are
>> subject to refcounting. Other than that, they only differ from package
>> variables in that they are not kept in a symbol-table but in so called
>> pads. Each block has its own pad and they are inaccessible from
>> pure-Perl (unless someone writes an XS extension that makes them
>> accessible).

>
> Maybe I misunderstand the above, but it seems to say that in the code
> snippet below, the lexical variable $x should not be seen by the
> 'eval' inside the block. But the output in the block is "r = 7" (while
> $y is 5, showing that the outer $x is unchanged), so 'eval' does see
> the lexical variable. What am I missing?


Why should 'eval' not see lexical variables? It does see them. It sees
the lexical $x here because inner lexicals override variables by that
name in an outer block.

> $e = '$x';
> $x = 5;
> *y = $x;


Did you mean to write

*y = \$x;

here?

> {
> my $x = 7;
> $r = eval $e;
> print "r = $r\n";
> print "outer r = $y\n";
> }
> $r = eval $e;
> print "r = $r\n";


With the change suggested above, I get:

r = 7
outer r = 5
r = 5

Is this not what you would expect?

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
Arndt Jonasson
Guest
Posts: n/a
 
      12-16-2004

"Tassilo v. Parseval" <(E-Mail Removed)> writes:
> Also sprach Arndt Jonasson:
>
> > "Tassilo v. Parseval" <(E-Mail Removed)> writes:
> >> As for lexical variables, technically they are not very different from
> >> package variables. They have the PADMY flag set which means they are
> >> subject to refcounting. Other than that, they only differ from package
> >> variables in that they are not kept in a symbol-table but in so called
> >> pads. Each block has its own pad and they are inaccessible from
> >> pure-Perl (unless someone writes an XS extension that makes them
> >> accessible).

> >
> > Maybe I misunderstand the above, but it seems to say that in the code
> > snippet below, the lexical variable $x should not be seen by the
> > 'eval' inside the block. But the output in the block is "r = 7" (while
> > $y is 5, showing that the outer $x is unchanged), so 'eval' does see
> > the lexical variable. What am I missing?

>
> Why should 'eval' not see lexical variables? It does see them. It sees
> the lexical $x here because inner lexicals override variables by that
> name in an outer block.
>
> > $e = '$x';
> > $x = 5;
> > *y = $x;

>
> Did you mean to write
>
> *y = \$x;
>
> here?


Oops, yes. Or *y=*x. I made the last change in the test program but
not in the article.

> With the change suggested above, I get:
>
> r = 7
> outer r = 5
> r = 5
>
> Is this not what you would expect?


It is, but "inaccessible from pure-Perl" made me think it might not
work. Does "inaccessible" simply mean that there is no package hash
table one can traverse to find the variable?
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-16-2004
Tassilo v. Parseval <(E-Mail Removed)> wrote in comp.lang.perl.misc:

> Aliases are a lot like hard links on Unices. You can delete the file
> that was hard-linked to but the hard link itself remains valid and
> behaves if it was the original file. ...


The analogy extends to the link count of a file, which has the same
function and reason-of-being as the refcount of a Perl variable.

Anno
 
Reply With Quote
 
Peter Scott
Guest
Posts: n/a
 
      12-16-2004
In article <(E-Mail Removed)>,
Arndt Jonasson <(E-Mail Removed)> writes:
>"Tassilo v. Parseval" <(E-Mail Removed)> writes:
>> Also sprach Arndt Jonasson:
>>
>> > "Tassilo v. Parseval" <(E-Mail Removed)> writes:
>> >> As for lexical variables, technically they are not very different from
>> >> package variables. They have the PADMY flag set which means they are
>> >> subject to refcounting. Other than that, they only differ from package
>> >> variables in that they are not kept in a symbol-table but in so called
>> >> pads. Each block has its own pad and they are inaccessible from
>> >> pure-Perl (unless someone writes an XS extension that makes them
>> >> accessible).

[snip]
> "inaccessible from pure-Perl" made me think it might not
>work. Does "inaccessible" simply mean that there is no package hash
>table one can traverse to find the variable?


Yes, but: http://search.cpan.org/~robin/PadWal...0/PadWalker.pm

--
Peter Scott
http://www.perldebugged.com/
*** NEW *** http://www.perlmedic.com/
 
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
XML + XSD: Is it possible to get all possible Values for an Element? Markus Java 1 11-22-2005 02:51 PM
is is possible to get Active X to work with Firefox? plus other minor things Trevor Smithson Firefox 5 06-04-2005 08:24 AM
Pointer to an array of structures, how to get it to work correclty, if possible??? mrhicks C Programming 1 07-16-2004 10:24 PM
Is there any possible way to get a 1394 CD drive to work with NT4? SGT Robo Computer Support 7 09-17-2003 03:33 AM



Advertisments