Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lexical packages leak into SETTING:: #5143

Open
p6rt opened this issue Feb 19, 2016 · 4 comments
Open

lexical packages leak into SETTING:: #5143

p6rt opened this issue Feb 19, 2016 · 4 comments
Labels
Bug

Comments

@p6rt
Copy link

@p6rt p6rt commented Feb 19, 2016

Migrated from rt.perl.org#127569 (status was 'open')

Searchable as RT127569$

@p6rt
Copy link
Author

@p6rt p6rt commented Feb 19, 2016

From @LLFourn

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 rakudo/rakudo#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.

@p6rt
Copy link
Author

@p6rt p6rt commented Aug 23, 2016

@coke - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

@p6rt p6rt commented Aug 23, 2016

From @coke

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.
# see rakudo/rakudo#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

@p6rt
Copy link
Author

@p6rt p6rt commented Aug 24, 2016

From @LLFourn

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​:

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.
# see rakudo/rakudo#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

@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.