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

facades, use_ok, and lexical export

0 views
Skip to first unread message

Gaal Yahas

unread,
Jan 9, 2006, 1:29:47 PM1/9/06
to perl6-l...@perl.org
Consider use_ok from the test system. Essentially, it should be

require $module; $module.import; pass "load $module";

in its caller's context. But now that exportation is lexical, how can
use_ok be implemented? It must divert the symbols installed by &import
and have them installed in the caller site. Can that be done in pure
Perl? Even before that: can &import be written in pure Perl?

This obviously won't work:

sub use_ok($module) {
eval "package {caller.package}; require etc.";
}

because the installation work happens at the wrong lexical scope, and
because pads can't be changed at runtime.

More generally, how does one write friendly facades that mix in some of
the functionality of their real modules? (Eg., "IO" in Perl 5 that loads
many IO::* modules) I am not sure Role composition will always be strong
enough to do this. For example if a module one wishes to pull in isn't a
Role :)


There are over a hundred "use_ok" in the Pugs test suite; we are about
to work around the problem by changing them to use+pass, but that's
obviously the Wrong Thing. Is there a better workaround / a better
design we could use?

--
Gaal Yahas <ga...@forum2.org>
http://gaal.livejournal.com/

Yuval Kogman

unread,
Jan 9, 2006, 1:46:43 PM1/9/06
to Gaal Yahas, perl6-l...@perl.org
What we need to do is find a way to do this at compile time.

One way is to make use_ok a macro.

The whole thing with linkage in Perl 6 is that it's supposed to
happen at compile time so that things are overall saner, but that it
can happen at runtime if we really really mean it.

use_ok as a function could simply import $module into the non
lexical scope because it's a runtime thing, unless it's made into a
macro/some other compile time construct, that is more declarative
in nature, and makes the whole process more opaque.

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &
/\ kung foo master: /me whallops greyface with a fnord: neeyah!!!!!!!

Luke Palmer

unread,
Jan 9, 2006, 4:34:41 PM1/9/06
to Gaal Yahas, perl6-l...@perl.org
On 1/9/06, Gaal Yahas <ga...@forum2.org> wrote:
> sub use_ok($module) {
> eval "package {caller.package}; require etc.";
> }

I'd like to see a nice interface to scopes in general. That is, we
would have a "scope object" which would provide access to all the
lexical scopes and the package scope of a particular call. So for
example, "use" might be written this way (handwaving over some details
of course):

macro use ($package, \$args) {
require $package;
$package.IMPORT(caller.scope, *$args);
}

So you could call IMPORT manually with whatever scope object you like
to get custom importation. But there may be something yet more
powerful...

> More generally, how does one write friendly facades that mix in some of
> the functionality of their real modules? (Eg., "IO" in Perl 5 that loads
> many IO::* modules) I am not sure Role composition will always be strong
> enough to do this. For example if a module one wishes to pull in isn't a
> Role :)

Maybe such a thing doesn't exist; i.e. all modules are roles of some
sort. I would like to see an object/module system all based on
composition. The design of Parse::Rule has shown me that it can be
very powerful, and if I didn't have to jump through ugly flaming hoops
to pull it off, that would be all the better.

A module's job is to "contain" things. So maybe you can do the same
thing you do with roles to any module: pull in the things it contains
and selectively override some of them. For example:

module Bar {
our class Foo {
has $.foo;
}
our Foo $FOO;
}

module Baz {
does Bar; # pull in the base module
our class Foo { # override the Foo member
does Bar::Foo; # hmm...
}
# $FOO is now of type Baz::Foo
# but we don't have to declare it;
# that's how overriding works
}

There's also probably a difference between module containment and
namespace levels; i.e. you wouldn't want to pull in the CGI module and
be able to override its Simple member.

Luke

0 new messages