Skip Menu |
Report information
Id: 127569
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: lloyd.fourn [at] gmail.com
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



From: Lloyd Fournier <lloyd.fourn [...] gmail.com>
To: "rakudobug [...] perl.org" <rakudobug [...] perl.org>
Date: Fri, 19 Feb 2016 02:37:48 +0000
Subject: lexical packages leak into SETTING::
Download (untitled) / with headers
text/plain 2.2k

When a package already exists in an outer scope, any package declared will insert itself into it even if it's meant to be lexically scoped. This includes the SETTING(s) (the most outer scopes). It is also problematic for our scoped things which manage to transcend the compunit interface's encapsulation of their globalish symbols.

This leads to a number of problems and inconsistencies. I believe it will be even more relevant when we try and implement jnthn++'s versioning design:

https://6guts.wordpress.com/2016/02/09/a-few-words-on-perl-6-versioning-and-compatibility/

Some examples:

## 1 leak out of lexical scope
{
   my module Cool::Utils { }
}
say Cool::Utils;

## 2 runtime symbol refers to something different to compile time symbol with same name
sub leaked-into {
      my class Cool::Utils { method doit { "one" } }
      say Cool::Utils.doit; #->one
      say ::("Cool::Utils").doit; #->two
}

{
      my class Cool::Utils { method doit { "two" } }
      leaked-into();
}

## 3 our scoped packages are not available for introspecting in CompUnit::Handle.globalish-package;

# lib/Cool/Utils.pm
class Cool::Utils {}
class Foo { };

# main.pl
my $cu = $*REPO.need(CompUnit::DependencySpecification.new(:short-name("Cool::Utils"));
say $cu.handle.globalish-package.WHO.keys; #-> (Foo)

# This was one of the things I didn't consider ( and isn't tested in require.t -- will do now) which caused problems with my patch.
# see https://github.com/rakudo/rakudo/pull/714 ugexe's comment.

------------

Another problem with our scoped packages inserting themselves into the setting is that when we have multiple settings which one of them does it insert it into?

What if a module like IO::Socket::SSL has 'use v6.c', so it never sees the 6.d setting. Then someone does:

use v6.d;
use IO::Socket::SSL;

If the 6.c-IO::Socket.WHO === 6.d-IO::Socket.WHO everything will be fine, but if not IO::Socket::SSL won't be visible to the 6.d code. It could copy itself to all the settings but that seems ugly to me.

The solution could be to create a special type of package used for declaring sub-packages of packages that already exist in an outer scope which could search it's own .WHO for the symbol before delegating to the outer scope package's WHO.

RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 2.5k
On Thu Feb 18 18:38:20 2016, lloyd.fourn@gmail.com wrote: Show quoted text
> When a package already exists in an outer scope, any package declared > will > insert itself into it even if it's meant to be lexically scoped. This > includes the SETTING(s) (the most outer scopes). It is also > problematic for > our scoped things which manage to transcend the compunit interface's > encapsulation of their globalish symbols. > > This leads to a number of problems and inconsistencies. I believe it > will > be even more relevant when we try and implement jnthn++'s versioning > design: > > https://6guts.wordpress.com/2016/02/09/a-few-words-on-perl-6- > versioning-and-compatibility/ > > Some examples: > > ## 1 leak out of lexical scope > { > my module Cool::Utils { } > } > say Cool::Utils; > > ## 2 runtime symbol refers to something different to compile time > symbol > with same name > sub leaked-into { > my class Cool::Utils { method doit { "one" } } > say Cool::Utils.doit; #->one > say ::("Cool::Utils").doit; #->two > } > > { > my class Cool::Utils { method doit { "two" } } > leaked-into(); > } > > ## 3 our scoped packages are not available for introspecting in > CompUnit::Handle.globalish-package; > > # lib/Cool/Utils.pm > class Cool::Utils {} > class Foo { }; > > # main.pl > my $cu = > $*REPO.need(CompUnit::DependencySpecification.new(:short- > name("Cool::Utils")); > say $cu.handle.globalish-package.WHO.keys; #-> (Foo) > > # This was one of the things I didn't consider ( and isn't tested in > require.t -- will do now) which caused problems with my patch. > # see https://github.com/rakudo/rakudo/pull/714 ugexe's comment. > > ------------ > > Another problem with our scoped packages inserting themselves into the > setting is that when we have multiple settings which one of them does > it > insert it into? > > What if a module like IO::Socket::SSL has 'use v6.c', so it never sees > the > 6.d setting. Then someone does: > > use v6.d; > use IO::Socket::SSL; > > If the 6.c-IO::Socket.WHO === 6.d-IO::Socket.WHO everything will be > fine, > but if not IO::Socket::SSL won't be visible to the 6.d code. It could > copy > itself to all the settings but that seems ugly to me. > > The solution could be to create a special type of package used for > declaring sub-packages of packages that already exist in an outer > scope > which could search it's own .WHO for the symbol before delegating to > the > outer scope package's WHO.
Not all the original code still compiles; can you revisit the request with new examples showing the issue? -- Will "Coke" Coleda
To: perl6-bugs-followup [...] perl.org
Subject: Re: [perl #127569] [BUG] lexical packages leak into SETTING::
Date: Wed, 24 Aug 2016 12:05:49 +0000
CC: perl6-compiler [...] perl.org
From: Lloyd Fournier <lloyd.fourn [...] gmail.com>
Download (untitled) / with headers
text/plain 3.3k
I was missing a ')' on the last one. Should be:

## 3 our scoped packages are not available for introspecting in CompUnit::Handle.globalish-package;

# lib/Cool/Utils.pm
class Cool::Utils {}
class Foo { };

# main.pl
my $cu = $*REPO.need(CompUnit::DependencySpecification.new(:short-name("Cool::Utils"));
say $cu.handle.globalish-package.WHO.keys; #-> (Foo)

^ Should be Foo and Cool::Utils

I heard that this and related issues might be solved by properly lexically scoping packages (ie scrapping GLOBALish):

http://irclog.perlgeek.de/perl6-dev/2016-08-15#i_13026138

But I dunno the details



On Wed, Aug 24, 2016 at 4:47 AM Will Coleda via RT <perl6-bugs-followup@perl.org> wrote:
Show quoted text
On Thu Feb 18 18:38:20 2016, lloyd.fourn@gmail.com wrote:
> When a package already exists in an outer scope, any package declared
> will
> insert itself into it even if it's meant to be lexically scoped. This
> includes the SETTING(s) (the most outer scopes). It is also
> problematic for
> our scoped things which manage to transcend the compunit interface's
> encapsulation of their globalish symbols.
>
> This leads to a number of problems and inconsistencies. I believe it
> will
> be even more relevant when we try and implement jnthn++'s versioning
> design:
>
> https://6guts.wordpress.com/2016/02/09/a-few-words-on-perl-6-
> versioning-and-compatibility/
>
> Some examples:
>
> ## 1 leak out of lexical scope
> {
>    my module Cool::Utils { }
> }
> say Cool::Utils;
>
> ## 2 runtime symbol refers to something different to compile time
> symbol
> with same name
> sub leaked-into {
>       my class Cool::Utils { method doit { "one" } }
>       say Cool::Utils.doit; #->one
>       say ::("Cool::Utils").doit; #->two
> }
>
> {
>       my class Cool::Utils { method doit { "two" } }
>       leaked-into();
> }
>
> ## 3 our scoped packages are not available for introspecting in
> CompUnit::Handle.globalish-package;
>
> # lib/Cool/Utils.pm
> class Cool::Utils {}
> class Foo { };
>
> # main.pl
> my $cu =
> $*REPO.need(CompUnit::DependencySpecification.new(:short-
> name("Cool::Utils"));
> say $cu.handle.globalish-package.WHO.keys; #-> (Foo)
>
> # This was one of the things I didn't consider ( and isn't tested in
> require.t -- will do now) which caused problems with my patch.
>
> ------------
>
> Another problem with our scoped packages inserting themselves into the
> setting is that when we have multiple settings which one of them does
> it
> insert it into?
>
> What if a module like IO::Socket::SSL has 'use v6.c', so it never sees
> the
> 6.d setting. Then someone does:
>
> use v6.d;
> use IO::Socket::SSL;
>
> If the 6.c-IO::Socket.WHO === 6.d-IO::Socket.WHO everything will be
> fine,
> but if not IO::Socket::SSL won't be visible to the 6.d code. It could
> copy
> itself to all the settings but that seems ugly to me.
>
> The solution could be to create a special type of package used for
> declaring sub-packages of packages that already exist in an outer
> scope
> which could search it's own .WHO for the symbol before delegating to
> the
> outer scope package's WHO.

Not all the original code still compiles; can you revisit the request with new examples showing the issue?

--
Will "Coke" Coleda


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org