Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

for 5.12: anonymous packages

0 views
Skip to first unread message

Ricardo SIGNES

unread,
Jan 10, 2008, 3:53:12 PM1/10/08
to perl5-...@perl.org

This was mentioned on #p5p today by mst, but I'm all for it. What's really
needed to make a package more than a string that looks up in %::? What would
it take to make it possible to have an anonymous package?

I use Package::Generator for this sort of thing, now, but it's pretty gross.

my $package = Symbol::table;
Symbol::set_variables(
$package => [
version => \1.00,
ISA => [ qw(Base OtherBase) ],
do_stuff => sub { ... }
],
);

I have *no* idea what is required to make this happen. I can see problems,
especially with things that already deal with symbol tables by expecting that
every package is just a string. There will need to be either magic or forward
incompatibility.

--
rjbs

Rafael Garcia-Suarez

unread,
Jan 10, 2008, 4:11:03 PM1/10/08
to Ricardo SIGNES, perl5-...@perl.org

We did have a form of anonymous package, which has been deprecated,
and that can be now replaced by something that works:

[rafael@stcosmo ~]$ perl5.8.8 -wepackage
Use of "package" with no arguments is deprecated at -e line 1.
[rafael@stcosmo ~]$ bleadperl -wepackage
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

However some more thought on the syntax is needed, of course.

Ricardo SIGNES

unread,
Jan 10, 2008, 9:05:16 PM1/10/08
to perl5-...@perl.org
* Rafael Garcia-Suarez <rgarci...@gmail.com> [2008-01-10T16:11:03]

> We did have a form of anonymous package, which has been deprecated,
> and that can be now replaced by something that works:
>
> [rafael@stcosmo ~]$ perl5.8.8 -wepackage
> Use of "package" with no arguments is deprecated at -e line 1.
> [rafael@stcosmo ~]$ bleadperl -wepackage
> syntax error at -e line 1, at EOF
> Execution of -e aborted due to compilation errors.

Yeah, at first I thought I'd suggest, in my sample:

my $package = package;

...and then I saw that 0-arg package existed. Its current behavior is bizarre,
though. Ditching it seems like a good idea, but then making "package" alone
return an anonymous package is just weird (to me).

I think we're better off with something new to return the anonymous package.

--
rjbs

Zefram

unread,
Jan 11, 2008, 6:18:06 AM1/11/08
to perl5-...@perl.org
Ricardo SIGNES wrote:
>Yeah, at first I thought I'd suggest, in my sample:
>
> my $package = package;

In my Class::Mix module (on CPAN), I had a need to create packages
dynamically for anonymous classes. I encapsulated that as the function
genpkg() in that module. It can't generate a package with literally
no name, of course, because packages are referred to strictly by their
character-string name. Instead it generates a name that is unlikely to
clash with anything deliberately constructed (and it checks that there
isn't actually a clash before returning the name). This is much like the
"gensym" concept seen in Lisp.

I think you'll have difficulty getting away from string names for
packages altogether. There's a lot of code that expects to do symbolic
referencing using package names and string operations. Better to
incorporate something like genpkg(). Suppose you were to allow an
arbitrary expression as the argument to "package", rather than just a
bareword, you could do things like:

use Class::Mix qw(genpkg);
package genpkg();
sub foo { 123 }
$main::anon_package = __PACKAGE__;

though actually to me that doesn't seem like a huge win over the present:

use Class::Mix qw(genpkg);
my $pkg = genpkg();
no strict "refs";
*{"$pkg\::foo"} = sub { 123 };
$main::anon_package = $pkg;

-zefram

Robert Sedlacek

unread,
Jan 11, 2008, 1:57:13 PM1/11/08
to perl5-...@perl.org

Sorry if this is a very bad idea, but what about:

my $anon = package {
sub new {
my ($p) = @_;
return bless {}, $p;
}
};

But what would $p be? Could there be a named package passed in like $p? For
example, could I do:

my $p = package Foo::Bar;

if (ref $p eq 'PACKAGE') {
print "Moo.\n";
}

Just my €0.02 :)


-rs

Ricardo SIGNES

unread,
Jan 11, 2008, 2:43:47 PM1/11/08
to perl5-...@perl.org
* Zefram <zef...@fysh.org> [2008-01-11T06:18:06]

> Ricardo SIGNES wrote:
> >Yeah, at first I thought I'd suggest, in my sample:
> >
> > my $package = package;
>
> In my Class::Mix module (on CPAN), I had a need to create packages
> dynamically for anonymous classes. I encapsulated that as the function
> genpkg() in that module. It can't generate a package with literally
> no name, of course, because packages are referred to strictly by their
> character-string name. Instead it generates a name that is unlikely to
> clash with anything deliberately constructed (and it checks that there
> isn't actually a clash before returning the name). This is much like the
> "gensym" concept seen in Lisp.

Right. This is what Package::Generator does, as well.

> I think you'll have difficulty getting away from string names for
> packages altogether. There's a lot of code that expects to do symbolic
> referencing using package names and string operations. Better to
> incorporate something like genpkg(). Suppose you were to allow an
> arbitrary expression as the argument to "package", rather than just a
> bareword, you could do things like:

Anonymous packages would, I'd hope, be scoped items that could be garbage
collected normally. (I that if in-scope X is blessed into package Y, there is
a reference to Y.)

Right now, I work around this, when necessary, with Package::Reaper.

--
rjbs

David Nicol

unread,
Jan 15, 2008, 9:04:28 AM1/15/08
to perl5-...@perl.org
On Jan 11, 2008 5:18 AM, Zefram <zef...@fysh.org> wrote:

> I think you'll have difficulty getting away from string names for
> packages altogether. There's a lot of code that expects to do symbolic
> referencing using package names and string operations. Better to
> incorporate something like genpkg(). Suppose you were to allow an
> arbitrary expression as the argument to "package", rather than just a
> bareword, you could do things like:
>
> use Class::Mix qw(genpkg);
> package genpkg();
> sub foo { 123 }
> $main::anon_package = __PACKAGE__;


use Macrame;
EXPAND "package HARD2GUESS".substr(rand(1),2);
no Macrame;
;

Stevan Little

unread,
Jan 17, 2008, 12:12:20 PM1/17/08
to perl5-...@perl.org, David Nicol

Alternately ...

my $anon_pkg = Class::MOP::Class->create_anon_class(
superclasses => [ 'Some::Base::Class' ],
methods => {
'foo' => sub { 123 },
'baz' => sub { 456 }
}
);

$main::anon_package = $anon_package->name;

This also has the added benefit/drawback that once $anon_package goes
out of scope the package will get deleted. It should be noted that if
you use the Class::MOP constructor, any instances of this anon-class
will hold a ref to the class and therefore keep it around as well.

- Stevan

Ricardo SIGNES

unread,
Jan 17, 2008, 1:29:49 PM1/17/08
to perl5-...@perl.org
* Stevan Little <stevan...@iinteractive.com> [2008-01-17T12:12:20]

> Alternately ...
>
> my $anon_pkg = Class::MOP::Class->create_anon_class(
> superclasses => [ 'Some::Base::Class' ],
> methods => {
> 'foo' => sub { 123 },
> 'baz' => sub { 456 }
> }
> );
>
> $main::anon_package = $anon_package->name;

See also:

my $reaper = Package::Reaper->new( Package::Generator->new_package( ... ) );

I wonder how many other solutions are out there.

--
rjbs

0 new messages