Mailing List Archive

constants, aliases and other curios
I was fooling around with the concept of generating constant scalars
in perl (with no code changes, can you believe it?) using the *foo = \$bar
trick. Turns out you can actually get a readonly global scalar with
simply:

*PI = \3.14159;

$PI can be used anywhere, but you can't modify it's value.

I went about in this vein for some time, until it struck me that this is
simply a type-specific aliasing operation. I went nuts thinking about
getting C++-like references with none of the dereferencing. At the end
of it all, the concept is quite workable and rather elegant, because
it gives you one less chance to use obfuscating typeglobs, and relief
from seeing a while lot of money $-) whenever you want to use references.

Socket/Fcntl/POSIX are obvious clients of this scheme.

Aliasing packages, is something that I haven't thought about before
sleep overcame.

Here's the result of one night's gallivanting with perl. I avidly welcome
your comments. (I hope this is one contribution to reducing "line noise",
and have true perl constants in the bargain).

- Sarathy.
gsar@engin.umich.edu
---------------------------------------8<-------------------------------------
package Alias;

=head1 NAME

Alias - declare aliases and constants


=head1 SYNOPSIS

use Alias qw(alias const);
alias TEN => $ten, Ten => \$ten, Ten => \&ten,
Ten => \@ten, Ten => \%ten, TeN => \*ten;
const pi => 3.14, ten => 10;


=head1 DESCRIPTION

Given a list of alias-symbol => value pairs, declares global aliases
in the caller's namespace. If the value supplied is a reference, the
alias is created for the underlying value instead of the reference
itself (since no one will use this package to alias references--they
are automatically "aliased" on assignment). This allows the user to
alias all of Perl's basic types.

If the value supplied is a compile-time constant, the aliases become
read-only. Any attempt to write to them will fail with a run time
error. A function-alias C<const> is aliased by this package (on demand)
for C<alias>, since this reads better for constant declarations.


=head1 EXAMPLE

use Alias qw(alias const);
$ten = 10;
alias TEN => $ten, Ten => \$ten, Ten => \&ten,
Ten => \@ten, Ten => \%ten;
alias TeN => \*ten; # same as *TeN = *ten
const _TEN_ => 10;

$ten = 20;
print "$TEN, $Ten, $ten\n";
sub ten { print "10\n"; }
@ten = (1..10);
%ten = (a..j);
&Ten;
print @Ten, %Ten;
$_TEN_ = 20;


=head1 NOTES

It is worth repeating that the aliases will be created in the
caller's namespace.

Aliases cannot be lexical, since, by necessity, they live on the
symbol table. They can be localized by first C<local>izing the
typeglob of the same name first, within the same block. However, this
will localize all the base types of the same name, and you will have
to deal with the consequences of that.

Remember that aliases are very much like references, only you
don't have to de-reference them as often.

It is possible to alias packages, but that might be construed as
abuse.

Using this package will lead to a much reduced urge to use typeglobs.


=head1 AUTHOR

Gurusamy Sarathy gsar@umich.edu

=cut

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(alias);
@EXPORT_OK = qw(const);

sub alias {
my($i) = scalar(@_) - 1 ;
my($j) = $i-1;
die "Need even number of args" if $j % 2;
my($pkg) = caller; # for namespace soundness
while ($j >= 0) {
if ('GLOB' eq ref $_[$i]) { eval "*$pkg\:\:$_[$j] = \${\$_[$i]}" }
elsif (ref $_[$i]) { eval "*$pkg\:\:$_[$j] = \$_[$i]" }
else { eval "*$pkg\:\:$_[$j] = \\\$_[$i]" }
$i--; $j--;
}
}

alias const => \&alias; # alias the alias :-)

1;
Re: constants, aliases and other curios [ In reply to ]
> From: Gurusamy Sarathy <gsar@engin.umich.edu>
>
> I was fooling around with the concept of generating constant scalars
> in perl (with no code changes, can you believe it?) using the *foo = \$bar
> trick.

Interesting.

No time for a detailed look right now but can't we avoid the evals these days:

> if ('GLOB' eq ref $_[$i]) { eval "*$pkg\:\:$_[$j] = \${\$_[$i]}" }
> elsif (ref $_[$i]) { eval "*$pkg\:\:$_[$j] = \$_[$i]" }
> else { eval "*$pkg\:\:$_[$j] = \\\$_[$i]" }

*{"..."} = \...{"..."} etc

Tim.
Re: constants, aliases and other curios [ In reply to ]
On Wed, 18 Oct 1995 18:20:52 BST, Tim Bunce wrote:
>
>> From: Gurusamy Sarathy <gsar@engin.umich.edu>
>>
>> I was fooling around with the concept of generating constant scalars
>> in perl (with no code changes, can you believe it?) using the *foo = \$bar
>> trick.
>
>Interesting.
>
>No time for a detailed look right now but can't we avoid the evals these days:
>
>> if ('GLOB' eq ref $_[$i]) { eval "*$pkg\:\:$_[$j] = \${\$_[$i]}" }
>> elsif (ref $_[$i]) { eval "*$pkg\:\:$_[$j] = \$_[$i]" }
>> else { eval "*$pkg\:\:$_[$j] = \\\$_[$i]" }
>
>*{"..."} = \...{"..."} etc
>
>Tim.
>

But of course. With that important optimization the code reads much
better:

if ('GLOB' eq ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = ${$_[$i]} }
elsif (ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = $_[$i] }
else { *{"$pkg\:\:$_[$j]"} = \$_[$i] }

Another interesting idea that is possibly more exciting (now that
I think about it), and seems even dangerous, is aliasing a lexical.
You can get a handle on a subroutine's pad lexical by aliasing
it to a global.

use Alias;

{
my $ten = 10;
alias TEN => \$ten;
print "$TEN|$ten";
$ten = 20;
}
print "|$TEN|$ten|";
__END__
10|10|20||

Which means you can selectively choose to keep alive certain
lexical values. Access to static vars? Asking for trouble?
The mind boggles. Yet I can't seem to get it to coredump :-)

- Sarathy.
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
This stuff is getting curiouser and curiouser. I just
realized that you can also have fully dynamically scoped
aliases, simply be pre-declaring the name as a local. You
don't ever need to use a glob for aliasing with this scheme.

Here's the latest Alias.pm with a significant addition
to the pod, and with the redundant C<eval>s excised.

- Sarathy.
gsar@engin.umich.edu
----------------------------------8<----------------------------------
#
# Documentation at the __END__
#

package Alias;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(alias);
@EXPORT_OK = qw(const);

sub alias {
my($i) = scalar(@_) - 1 ;
my($j) = $i-1;
die "Need even number of args" if $j % 2;
my($pkg) = caller; # for namespace soundness
while ($j >= 0) {
if ('GLOB' eq ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = ${$_[$i]} }
elsif (ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = $_[$i] }
else { *{"$pkg\:\:$_[$j]"} = \$_[$i] }
$i--; $j--;
}
}

alias const => \&alias; # alias the alias :-)

1;
__END__

=head1 NAME

Alias - declare perl aliases and constants


=head1 SYNOPSIS

use Alias qw(alias const);
alias TEN => $ten, Ten => \$ten, Ten => \&ten,
Ten => \@ten, Ten => \%ten, TeN => \*ten;
{
local @Ten;
my $ten = [1..10];
alias Ten => $ten; # local @Ten
}

const pi => 3.14, ten => 10;


=head1 DESCRIPTION

Given a list of alias-symbol => value pairs, declares aliases
in the caller's namespace. If the value supplied is a reference, the
alias is created for the underlying value instead of the reference
itself (since no one will use this package to alias references--they
are automatically "aliased" on assignment). This allows the user to
alias all of Perl's basic types.

If the value supplied is a compile-time constant, the aliases become
read-only. Any attempt to write to them will fail with a run time
error. A function-alias C<const> is aliased by this package (on demand)
for C<alias>, since this reads better for constant declarations.

Aliases can be dynamically scoped by pre-declaring the target symbol as
a C<local>.


=head1 EXAMPLES

use Alias qw(alias const);
$ten = 10;
alias TEN => $ten, Ten => \$ten, Ten => \&ten,
Ten => \@ten, Ten => \%ten;
alias TeN => \*ten; # same as *TeN = *ten
const _TEN_ => 10;

$ten = 20;
print "$TEN|$Ten|$ten\n";
sub ten { print "10\n"; }
@ten = (1..10);
%ten = (a..j);
&Ten;
print @Ten, "|", %Ten, "\n";

@DYNAMIC = qw(m n o);
{
my $tmp = [ qw(a b c d) ];
local @DYNAMIC;
alias DYNAMIC => $tmp, PERM => $tmp;
$DYNAMIC[2] = 'zzz';
print @$tmp, "|", @DYNAMIC, "|", @PERM, "\n";
@DYNAMIC = qw(p q r);
print @$tmp, "|", @DYNAMIC, "|", @PERM, "\n";
}
print @DYNAMIC, "|", @PERM, "\n";

$_TEN_ = 20;


=head1 NOTES

It is worth repeating that the aliases will be created in the caller's
namespace. If that namespace happens to be C<local>ized, the alias
created will be local to that block. This enables the use of dynamically
scoped aliases.

Aliases cannot be lexical, since, by necessity, they live on the
symbol table.

Lexicals can be aliased. Note that this gives us a means of reversing
the action of anonymous type generators C<\>, C<[]> and C<{}>. Which
means you can anonymously construct data and give it a symboltable
presence when you choose.

Remember that aliases are very much like references, only you don't
have to de-reference them as often. Which means you won't have to
pound on the dollars so much.

It is possible to alias packages, but that might be construed as
abuse.

Using this package will lead to a much reduced urge to use typeglobs.


=head1 AUTHOR

Gurusamy Sarathy gsar@umich.edu

=cut
Re: constants, aliases and other curios [ In reply to ]
> Here's the latest Alias.pm with a significant addition
> to the pod, and with the redundant C<eval>s excised.

Which opens of course a tough question: to CPAN or not to CPAN? Version?

If it had a version number, I'd put it into a tar with your message as
Announce file. But without, I'd rather ask you.

It's really blech to have packages that are so small, but maybe it's
better than nothing. At least, that's what CPAN stands for :)


----


Thanks, Sarathy, your patch built fine, and my default perl contains
your patch already.


Keep up your golden work,
andreas
Re: constants, aliases and other curios [ In reply to ]
On Fri, 20 Oct 1995 08:35:57 BST, Andreas Koenig wrote:
>
> > Here's the latest Alias.pm with a significant addition
> > to the pod, and with the redundant C<eval>s excised.
>
>Which opens of course a tough question: to CPAN or not to CPAN? Version?
>
>If it had a version number, I'd put it into a tar with your message as
>Announce file. But without, I'd rather ask you.

I was going to suggest this myself.. You can call it version 1.0.
Many thanks.

It needs a module list entry as well. I see some potential in the package
for aggrandization, so it'll get bigger in time :-)

>
>It's really blech to have packages that are so small, but maybe it's
>better than nothing. At least, that's what CPAN stands for :)
>
>Thanks, Sarathy, your patch built fine, and my default perl contains
>your patch already.
>

Thanks.

>
>Keep up your golden work,
>andreas
>

- Sarathy.
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
> From: Andreas Koenig <k@anna.mind.de>
>
> > Here's the latest Alias.pm with a significant addition
> > to the pod, and with the redundant C<eval>s excised.
>
> Which opens of course a tough question: to CPAN or not to CPAN? Version?

I'd be very interested in Larry's comments on this approach.

> It's really blech to have packages that are so small,

Why?

I like modules which are lean, mean and well focused much more than
I-added-everything-I-could-think-of modules.

Tim.
Re: constants, aliases and other curios [ In reply to ]
>>>>> "tim" == Tim Bunce <Tim.Bunce@ig.co.uk> writes:

>> It's really blech to have packages that are so small,

tim> Why?

Scratch what I said. Was before breakfast and before tea and after I
released MakeMaker :)

Sure I'm fond of Sarathy's small works.

Time for another vote to include Dumper in 5.002 (after a
namechange). I'd certainly use it within MakeMaker to record
installations history.

Regards,
andreas
Re: constants, aliases and other curios [ In reply to ]
: Another interesting idea that is possibly more exciting (now that
: I think about it), and seems even dangerous, is aliasing a lexical.
: You can get a handle on a subroutine's pad lexical by aliasing
: it to a global.
:
: use Alias;
:
: {
: my $ten = 10;
: alias TEN => \$ten;
: print "$TEN|$ten";
: $ten = 20;
: }
: print "|$TEN|$ten|";
: __END__
: 10|10|20||
:
: Which means you can selectively choose to keep alive certain
: lexical values. Access to static vars? Asking for trouble?
: The mind boggles. Yet I can't seem to get it to coredump :-)

It better not. This is precisely the same mechanism used by closures,
only the alias is in the pad of the closure. ANY extra reference to a
lexical variable's value causes the value to be spun off rather than
discarded when the lexical goes out of scope. You're also doing the
same thing when you bless a reference to "my $foo" and return it.

Larry
Re: constants, aliases and other curios [ In reply to ]
On Fri, 20 Oct 1995 15:20:06 BST, Andreas Koenig wrote:
>
>Time for another vote to include Dumper in 5.002 (after a
>namechange). I'd certainly use it within MakeMaker to record
>installations history.
>

Real soon now, the latest version of Dumper (to be called Data::Dump in line
with discussion on packrats), is going to be released, as soon as I
write a decent pod for it. This offers an OO interface that is much more
versatile in associating nested references with names supplied, controlling
indenting etc. All of those features are being used in the upcoming Tkperldb.

Ilya has done significant work on dumpvar.pl, too. I think Data::Dump
overlaps much of that functionality. I need to look closely at Ilya's
dumpvar, so Data::Dump can assimilate the extras and serve as a generic
module for both perl5db and Tkperldb. This will happen this weekend most
likely.

>Regards,
>andreas
>

- Sarathy.
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
On Fri, 20 Oct 1995 10:09:19 PDT, Larry Wall wrote:
>: Which means you can selectively choose to keep alive certain
>: lexical values. Access to static vars? Asking for trouble?
>: The mind boggles. Yet I can't seem to get it to coredump :-)
>
>It better not. This is precisely the same mechanism used by closures,
>only the alias is in the pad of the closure. ANY extra reference to a
>lexical variable's value causes the value to be spun off rather than
>discarded when the lexical goes out of scope. You're also doing the
>same thing when you bless a reference to "my $foo" and return it.
>

What I like most about aliasing is the fact that you can get back
basic types from references without none of the ${..} skulduggery. To
hear that this is a robust-as-designed concept makes me very happy.

Now, if only there was a way to have lexical aliases, the perl world can be
made much rounder for many people. But I won't belabor that one. Larry
doesn't need my urging to continue working his miracles, I am sure :-)

- Sarathy.
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
In article <199510200659.CAA00336@aatma.engin.umich.edu> you write:

>sub alias {
> my($i) = scalar(@_) - 1 ;
> my($j) = $i-1;
> die "Need even number of args" if $j % 2;
> my($pkg) = caller; # for namespace soundness
> while ($j >= 0) {
> if ('GLOB' eq ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = ${$_[$i]} }
> elsif (ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = $_[$i] }
> else { *{"$pkg\:\:$_[$j]"} = \$_[$i] }
> $i--; $j--;
> }
>}

Shouldn't that be $i -= 2; $j -= 2; , or am I missing something?

I'd usually use "shift" doing this sort of thing, and I like the :?
operator:

use Carp;
sub alias {
my $pkg = caller; # for namespace soundness
while ( @_ ) {
my ($from, $to) = (shift, shift);
croak "alias needs even number of args" unless defined $to;
*{"$pkg\:\:$from"} = ref $to ? ref $to eq GLOB ? $$to : $to : \$to;
}
}

NB - there's also a rearrangement of the conditionals needed, even if
you don't like ??:: - test for the "ref" first, then for ref eq GLOB.
Otherwise " alias 'TEN'=>$ten; " provokes an "undefined reference" warning.

NB2 - yes, \$to is a reference to the actual parameter.

BTW - that double-quoted string irks me. I feel sure there ought to be a
syntax for accessing the package/variable without having to concatenate
bits (which perl will immediately split apart again), but for the life
of me I can't think what it might be...

Ian
Re: constants, aliases and other curios [ In reply to ]
On Sun, 22 Oct 1995 14:30:39 GMT, ian wrote:
>In article <199510200659.CAA00336@aatma.engin.umich.edu> you write:
>
>>sub alias {
>> my($i) = scalar(@_) - 1 ;
>> my($j) = $i-1;
>> die "Need even number of args" if $j % 2;
>> my($pkg) = caller; # for namespace soundness
>> while ($j >= 0) {
>> if ('GLOB' eq ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = ${$_[$i]} }
>> elsif (ref $_[$i]) { *{"$pkg\:\:$_[$j]"} = $_[$i] }
>> else { *{"$pkg\:\:$_[$j]"} = \$_[$i] }
>> $i--; $j--;
>> }
>>}
>
>Shouldn't that be $i -= 2; $j -= 2; , or am I missing something?

But of course. And I'm ashamed of my sloppiness :-(

>
>I'd usually use "shift" doing this sort of thing, and I like the :?
>operator:
>
>use Carp;
>sub alias {
> my $pkg = caller; # for namespace soundness
> while ( @_ ) {
> my ($from, $to) = (shift, shift);

That will not preserve referenceness to the original value if $to is
not a ref. That's the reason why I use $_[$i] all over the place. And
that leads to the $i, $j mess.

> croak "alias needs even number of args" unless defined $to;
> *{"$pkg\:\:$from"} = ref $to ? ref $to eq GLOB ? $$to : $to : \$to;
> }
>}
>
>NB - there's also a rearrangement of the conditionals needed, even if
>you don't like ??:: - test for the "ref" first, then for ref eq GLOB.
>Otherwise " alias 'TEN'=>$ten; " provokes an "undefined reference" warning.

Yes, and while we are at it, we might as well fix it to be safe against
undefined values as well. I think

*{"$pkg\:\:$_[$j]"} = (defined($_[$i]) && ref($_[$i])) ?
(ref($_[$i]) eq 'GLOB') ? ${$_[$i]} : $_[$i] : \$_[$i];

should do it right. And I prefer croaking up ahead if there are odd number
of args. This is another reason for the $i, $j mess.

>
>NB2 - yes, \$to is a reference to the actual parameter.

Only if $to is a ref. Else it is a copy. Which means this won't work
to produce constants. This should cause a run time error but it doesn't
in your version:

use Alias;
alias TEN => 10;
$TEN = 20;

>
>BTW - that double-quoted string irks me. I feel sure there ought to be a
>syntax for accessing the package/variable without having to concatenate
>bits (which perl will immediately split apart again), but for the life
>of me I can't think what it might be...

You could use "." but that won't be anymore efficient.

>
>Ian
>

Thanks very much for your comments Ian, I have attached a copy of the
package with the changes, and (wonder of wonders) an exciting new addition
to the pod, named closures.

- Sarathy.
gsar@engin.umich.edu

P.S: If you've read this far Andreas, please replace with this version
on CPAN. Thanks.
----------------------------------8<-------------------------------------
#
# Documentation at the __END__
#

package Alias;

require 5.001;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(alias);
@EXPORT_OK = qw(const);

use Carp;

sub alias {
my($i) = scalar(@_) - 1 ;
my($j) = $i-1;
croak "Need even number of args" if $j % 2;
my($pkg) = caller; # for namespace soundness
while ($j >= 0) {
*{"$pkg\:\:$_[$j]"} = (defined($_[$i]) && ref($_[$i])) ?
(ref($_[$i]) eq 'GLOB') ? ${$_[$i]} : $_[$i] : \$_[$i];
$i -= 2; $j -= 2;
}
}

alias const => \&alias; # alias the alias :-)

1;
__END__

=head1 NAME

Alias - declare perl aliases and constants


=head1 SYNOPSIS

use Alias qw(alias const);
alias TEN => $ten, Ten => \$ten, Ten => \&ten,
Ten => \@ten, Ten => \%ten, TeN => \*ten;
{
local @Ten;
my $ten = [1..10];
alias Ten => $ten; # local @Ten
}

const pi => 3.14, ten => 10;


=head1 DESCRIPTION

Given a list of alias-symbol => value pairs, declares aliases
in the caller's namespace. If the value supplied is a reference, the
alias is created for the underlying value instead of the reference
itself (since no one will use this package to alias references--they
are automatically "aliased" on assignment). This allows the user to
alias all of Perl's basic types.

If the value supplied is a compile-time constant, the aliases become
read-only. Any attempt to write to them will fail with a run time
error. A function-alias C<const> is aliased by this package (on demand)
for C<alias>, since this reads better for constant declarations.

Aliases can be dynamically scoped by pre-declaring the target symbol as
a C<local>.


=head1 EXAMPLES

use Alias qw(alias const);
$ten = 10;
alias TEN => $ten, Ten => \$ten, Ten => \&ten,
Ten => \@ten, Ten => \%ten;
alias TeN => \*ten; # same as *TeN = *ten
const _TEN_ => 10;

# aliasing basic types
$ten = 20;
print "$TEN|$Ten|$ten\n";
sub ten { print "10\n"; }
@ten = (1..10);
%ten = (a..j);
&Ten;
print @Ten, "|", %Ten, "\n";

# dynamically scoped aliases
@DYNAMIC = qw(m n o);
{
my $tmp = [ qw(a b c d) ];
local @DYNAMIC;
alias DYNAMIC => $tmp, PERM => $tmp;
$DYNAMIC[2] = 'zzz';
print @$tmp, "|", @DYNAMIC, "|", @PERM, "\n";
@DYNAMIC = qw(p q r);
print @$tmp, "|", @DYNAMIC, "|", @PERM, "\n";
}
print @DYNAMIC, "|", @PERM, "\n";

# named closures
my($lex) = 'abcd';
$closure = sub { print $lex, "\n" };
alias NAMEDCLOSURE => \&$closure;
NAMEDCLOSURE();
$lex = 'pqrs';
NAMEDCLOSURE();

# should lead to run-time error
$_TEN_ = 20;


=head1 NOTES

It is worth repeating that the aliases will be created in the caller's
namespace. If that namespace happens to be C<local>ized, the alias
created will be local to that block. This enables the use of dynamically
scoped aliases.

Aliases cannot be lexical, since, by necessity, they live on the
symbol table.

Lexicals can be aliased. Note that this gives us a means of reversing
the action of anonymous type generators C<\>, C<[]> and C<{}>. Which
means you can anonymously construct data and give it a symbol-table
presence when you choose.

Remember that aliases are very much like references, only you don't
have to de-reference them as often. Which means you won't have to
bounce on Shift-4 so much.

You can make named closures with this scheme, by simply aliasing
a closure and giving it a symbol table presence.

It is possible to alias packages, but that might be construed as
abuse.

Using this package will lead to a much reduced urge to use typeglobs.


=head1 VERSION

1.2 Bugfix in the while loop, and other cleanup. Thanks to Ian Phillips
<ian@pipex.net>.

1.1 Added named closures to pod

1.0 Released to perl5-porters@nicoh.com


=head1 AUTHOR

Gurusamy Sarathy gsar@umich.edu

=cut
Re: constants, aliases and other curios [ In reply to ]
Gurusamy Sarathy writes:
>
> You can make named closures with this scheme, by simply aliasing
> a closure and giving it a symbol table presence.
>

This may need to be reworked, since named closures are in teh language
much longer that even the time we wait for 5.002.

I have some vague conjecture about what you mean,
named-factory-produced-closures, but if you can word it, please do. Or
maybe I missing what is a closure?

Ilya
Re: constants, aliases and other curios [ In reply to ]
On Sun, 22 Oct 1995 14:14:57 EDT, Ilya Zakharevich wrote:
>Gurusamy Sarathy writes:
>>
>> You can make named closures with this scheme, by simply aliasing
>> a closure and giving it a symbol table presence.
>>
>
>This may need to be reworked, since named closures are in teh language
>much longer that even the time we wait for 5.002.
>

Do you mean expanded and described in more detail?

>I have some vague conjecture about what you mean,
>named-factory-produced-closures, but if you can word it, please do. Or
>maybe I missing what is a closure?

Up till now I had assumed that closures are always anonymous.
This demonstrates that they can easily have a symbol table presence
as well. Also, it is trivial to make local subroutines that can
also be closures:

use Alias;
{
local *LOCALSUB; # too bad this can't be ${\&LOCALSUB}
my $bar = "bar";
alias LOCALSUB => sub { print "foo", $bar, "\n" },
GLOBALSUB => sub { print "fuz", $bar, "\n" };
LOCALSUB();
$bar = "buz";
LOCALSUB();
}
GLOBALSUB();
LOCALSUB();
__END__
foobar
foobuz
fuzbuz
Undefined subroutine &main::LOCALSUB called at - line 12.

I can't think of a better name for them than "named closures" though.
Let me know if some one else can.

This *foo = \$bar feature in perl is a genuine pearl that keeps throwing
up new amazing things. Thank you Larry!

>
>Ilya
>

- Sarathy.
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
Gurusamy Sarathy <gsar@engin.umich.edu> wrote:

> That will not preserve referenceness to the original value if $to is
> not a ref. That's the reason why I use $_[$i] all over the place. And
> that leads to the $i, $j mess.

Hmm.. I convinced myself otherwise. Sorry, my mistake. I just
un-convinced myself again.

> Yes, and while we are at it, we might as well fix it to be safe against
> undefined values as well. I think
>
> *{"$pkg\:\:$_[$j]"} = (defined($_[$i]) && ref($_[$i])) ?
> (ref($_[$i]) eq 'GLOB') ? ${$_[$i]} : $_[$i] : \$_[$i];

> should do it right. And I prefer croaking up ahead if there are odd number
> of args. This is another reason for the $i, $j mess.

Fair enough, but you can say croak ... if @_ % 2;

> >NB2 - yes, \$to is a reference to the actual parameter.
> Only if $to is a ref. Else it is a copy. Which means this won't work

[Hangs head in shame]

> >BTW - that double-quoted string irks me. I feel sure there ought to be a
> You could use "." but that won't be anymore efficient.

I think that Perl changes it into this form anyway. I was trying to
think of some way of avoiding joining it all together, only to have the
evaluator split it again.

However, I never give up :-)

sub alias {
croak "Need even number of args" if @_ % 2;
my($pkg) = caller; # for namespace soundness
do {
*{"$pkg\:\:$_[0]"} = (defined($_[1]) && ref($_[1])) ?
(ref($_[1]) eq 'GLOB') ? ${$_[1]} : $_[1] : \$_[1];
} while shift and shift;
}

Ian
Re: constants, aliases and other curios [ In reply to ]
On Sun, 22 Oct 1995 21:36:51 -0000, Ian Phillipps wrote:
>
>However, I never give up :-)
>
>sub alias {
> croak "Need even number of args" if @_ % 2;
> my($pkg) = caller; # for namespace soundness
> do {
> *{"$pkg\:\:$_[0]"} = (defined($_[1]) && ref($_[1])) ?
> (ref($_[1]) eq 'GLOB') ? ${$_[1]} : $_[1] : \$_[1];
> } while shift and shift;
>}

Yo! However, that will not alias the last pair of args if
the last is "", 0 or undef. Try

use Alias;
alias TRUE => 1, FALSE => 0;

$FALSE will not initialize as it does now.

>
>Ian
(the irrepressible) :-)
>

- Sarathy. (having just the right amount of fun)
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
On Sun, 22 Oct 1995 19:52:20 EDT, I deluded:
>
>Yo! However, that will not alias the last pair of args if
>the last is "", 0 or undef. Try
>
> use Alias;
> alias TRUE => 1, FALSE => 0;
>
>$FALSE will not initialize as it does now.
>

Er, you won't able to see the problem with that, the example must have been
written:

use Alias;
alias FALSE => 0, TRUE => 1; # $TRUE wont be set

- Sarathy.
gsar@engin.umich.edu
Re: constants, aliases and other curios [ In reply to ]
Excerpts from the mail message of Gurusamy Sarathy:
)
) On Sun, 22 Oct 1995 21:36:51 -0000, Ian Phillipps wrote:
) >sub alias {
) > croak "Need even number of args" if @_ % 2;
) > my($pkg) = caller; # for namespace soundness
) > do {
) > *{"$pkg\:\:$_[0]"} = (defined($_[1]) && ref($_[1])) ?
) > (ref($_[1]) eq 'GLOB') ? ${$_[1]} : $_[1] : \$_[1];
) > } while shift and shift;
) >}
)
) Yo! However, that will not alias the last pair of args if
) the last is "", 0 or undef. Try

I do it this way every so often:

sub alias {
croak "Need even number of args" if @_ % 2;
my($pkg) = caller; # for namespace soundness
while( @_ ) {
*{$pkg."::".$_[0]} = (defined($_[1]) && ref($_[1])) ?
(ref($_[1]) eq 'GLOB') ? ${$_[1]} : $_[1] : \$_[1];
splice(@_,0,2);
}
}

--
Tye McQueen tye@metronet.com || tye@doober.usu.edu
Nothing is obvious unless you are overlooking something
http://www.metronet.com/~tye/ (scripts, links, nothing fancy)