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

.wrap doesn't work for routines declared in roles #4974

Open
p6rt opened this issue Jan 1, 2016 · 6 comments
Open

.wrap doesn't work for routines declared in roles #4974

p6rt opened this issue Jan 1, 2016 · 6 comments

Comments

@p6rt
Copy link

p6rt commented Jan 1, 2016

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

Searchable as RT127112$

@p6rt
Copy link
Author

p6rt commented Jan 1, 2016

From @LLFourn

role Foo {
  sub foo { };
  BEGIN &foo.wrap(-> {});
}

@p6rt
Copy link
Author

p6rt commented Jan 1, 2016

From @LLFourn

should have mentioned, this is the error msg​:

===SORRY!=== Error while compiling
  Cannot invoke this object

On Sat, Jan 2, 2016 at 3​:49 AM perl6 via RT <perl6-bugs-followup@​perl.org>
wrote​:

Greetings,

This message has been automatically generated in response to the
creation of a trouble ticket regarding​:
".wrap doesn't work for routines declared in roles",
a summary of which appears below.

There is no need to reply to this message right now. Your ticket has been
assigned an ID of [perl #​127112].

Please include the string​:

     \[perl #&#8203;127112\]

in the subject line of all future correspondence about this issue. To do
so,
you may reply to this message.

                    Thank you,
                    perl6\-bugs\-followup@&#8203;perl\.org

-------------------------------------------------------------------------
role Foo {
sub foo { };
BEGIN &foo.wrap(-> {});
}

@p6rt
Copy link
Author

p6rt commented Jan 2, 2016

From @LLFourn

I golfed this down to​:

p6 -e 'role {sub foo {}; BEGIN &foo.clone() }'

===SORRY!=== Error while compiling -e
An exception occurred while evaluating a BEGIN
at -e​:1
Exception details​:
  ===SORRY!=== Error while compiling
  Cannot invoke this object
  at :

For reasons I don't quite understand it's not using the right clone. If you
use Mu​::clone directly it works​:

p6 -e 'role {sub foo {}; BEGIN &foo.Mu​::clone() }'

On Sat, Jan 2, 2016 at 3​:58 AM Lloyd Fournier <lloyd.fourn@​gmail.com> wrote​:

should have mentioned, this is the error msg​:

===SORRY!=== Error while compiling
Cannot invoke this object

On Sat, Jan 2, 2016 at 3​:49 AM perl6 via RT <perl6-bugs-followup@​perl.org>
wrote​:

Greetings,

This message has been automatically generated in response to the
creation of a trouble ticket regarding​:
".wrap doesn't work for routines declared in roles",
a summary of which appears below.

There is no need to reply to this message right now. Your ticket has been
assigned an ID of [perl #​127112].

Please include the string​:

     \[perl #&#8203;127112\]

in the subject line of all future correspondence about this issue. To do
so,
you may reply to this message.

                    Thank you,
                    perl6\-bugs\-followup@&#8203;perl\.org

-------------------------------------------------------------------------
role Foo {
sub foo { };
BEGIN &foo.wrap(-> {});
}

@p6rt
Copy link
Author

p6rt commented Jan 2, 2016

From @lizmat

On 01 Jan 2016, at 17​:49, Lloyd Fournier (via RT) <perl6-bugs-followup@​perl.org> wrote​:

# New Ticket Created by Lloyd Fournier
# Please include the string​: [perl #​127112]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127112 >

role Foo {
sub foo { };
BEGIN &foo.wrap(-> {});
}

One should realize that a role is nothing but a place-holder for code to be inserted when it is either does’d by a class, or punned into a class. It doesn't execute code in the mainline of the role after it has been parsed. Unless you use BEGIN of course.

If you remove the BEGIN from you example, I *think* it does what you expect it to​:

role Foo {
  sub foo { };
  &foo.wrap(-> { "foo" });

  say "mainline";

  method a { foo }
}

BEGIN say "role done";

say Foo.a

role done
mainline
foo

Note that the “mainline” is executed *after* the BEGIN block after the role.

Disallowing BEGIN blocks inside a role, might be an option. OTOH, there might be valid uses for that as well, doing MOPpy things.

So, all in all, I think this is a case of an LTA error. Is that what you intended to report?

Liz

@p6rt
Copy link
Author

p6rt commented Jan 2, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jan 2, 2016

From @LLFourn

Hey Liz,

Sorry this was a case of me golfing something down then not explaining the
.WHY of what I was originally doing. This is what I was trying to achieve.

multi trait_mod​:<is>(Routine​:D $meth,​:$baz!) {
  $meth.wrap( -> \SELF,$subj {});
};

role Foo {
  method foo is baz { };
}

Obviously traits are run at compile time. To me if you can't use a trait
that wraps a method in a role that's a very weird and annoying
inconsistency.

Also I don't think there is any architectural reason why methods in roles
can't be .wrap'd, I think it's just an edge case that hasn't been tested
for yet. As I showed above it's happening in .clone which for some reason
(which I would love to understand) is not Mu​::clone but some bootstrapping
clone​:

Lloyds-iMac​:~ llfourn$ perl6 -e 'sub foo { }; BEGIN
&foo.^find_method("clone").^name.say'
ForeignCode

On Sat, Jan 2, 2016 at 9​:14 PM Elizabeth Mattijsen via RT <
perl6-bugs-followup@​perl.org> wrote​:

On 01 Jan 2016, at 17​:49, Lloyd Fournier (via RT) <
perl6-bugs-followup@​perl.org> wrote​:

# New Ticket Created by Lloyd Fournier
# Please include the string​: [perl #​127112]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127112 >

role Foo {
sub foo { };
BEGIN &foo.wrap(-> {});
}

One should realize that a role is nothing but a place-holder for code to
be inserted when it is either does’d by a class, or punned into a class.
It doesn't execute code in the mainline of the role after it has been
parsed. Unless you use BEGIN of course.

If you remove the BEGIN from you example, I *think* it does what you
expect it to​:

role Foo {
sub foo { };
&foo.wrap(-> { "foo" });

say "mainline";

method a \{ foo \}

}

BEGIN say "role done";

say Foo.a

role done
mainline
foo

Note that the “mainline” is executed *after* the BEGIN block after the
role.

Disallowing BEGIN blocks inside a role, might be an option. OTOH, there
might be valid uses for that as well, doing MOPpy things.

So, all in all, I think this is a case of an LTA error. Is that what you
intended to report?

Liz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant