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

Private Methods/Attributes in roles do not work as expected #6379

Open
p6rt opened this issue Jul 5, 2017 · 10 comments
Open

Private Methods/Attributes in roles do not work as expected #6379

p6rt opened this issue Jul 5, 2017 · 10 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Jul 5, 2017

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

Searchable as RT131707$

@p6rt
Copy link
Author

p6rt commented Jul 5, 2017

From martin@senfdax.de

Hi there,

this is crossposed in the perl6-users mailing list. Since noone stopped
me from assuming that this is a bug, i am going to open this now​:

Assuming those two files A.pm and B.pm.

The file A.pm contains a class A and a role R with a private-method and
a $!private member. (the files are in the end of the e-mail)

1) I am wondering why a role can all its private methods​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.public-method()'
priv method

2) but can't write its private members​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.set_private(A.new); $b.r'
No such private method '!!private' for invocant of type 'B'
  in method set_private at /home/martin/.workspace/p6/realerror/A.pm
(A) line 24
  in block <unit> at -e line 1

WHEN! the set_private looks like this​:

  method set_private(A $a) {
  self!private = $a;
  }

3) It seems to work (well, it gets a error a bit later in $b.r)​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.set_private(A.new); $b.r
'
P6opaque​: no such attribute '$!private' in type B when trying to get a
value
  in method s at /home/martin/.workspace/p6/realerror/A.pm (A) line 11
  in method s at /home/martin/.workspace/p6/realerror/A.pm (A) line 11
  in method r at /home/martin/.workspace/p6/realerror/A.pm (A) line 6
  in block <unit> at -e line 1

WHEN set_private looks like this​:

  method set_private(A $a) {
  $!private = $a;
  }

But method !s seems to be broken now.

I dont get why :( i would expect this to work. :-(

In addition I think the error message is broken​: "No such private method
'!!private' for invocant of type 'B'" it was differently in 2016.11

@p6rt
Copy link
Author

p6rt commented Jul 6, 2017

From @zoffixznet

On Wed, 05 Jul 2017 09​:09​:48 -0700, martin@​senfdax.de wrote​:

Hi there,

this is crossposed in the perl6-users mailing list. Since noone stopped
me from assuming that this is a bug, i am going to open this now​:

Assuming those two files A.pm and B.pm.

The file A.pm contains a class A and a role R with a private-method and
a $!private member. (the files are in the end of the e-mail)

1) I am wondering why a role can all its private methods​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.public-method()'
priv method

2) but can't write its private members​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.set_private(A.new); $b.r'
No such private method '!!private' for invocant of type 'B'
in method set_private at /home/martin/.workspace/p6/realerror/A.pm
(A) line 24
in block <unit> at -e line 1

WHEN! the set_private looks like this​:

 method set\_private\(A $a\) \{
     self\!private = $a;
 \}

3) It seems to work (well, it gets a error a bit later in $b.r)​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.set_private(A.new); $b.r
'
P6opaque​: no such attribute '$!private' in type B when trying to get a
value
in method s at /home/martin/.workspace/p6/realerror/A.pm (A) line 11
in method s at /home/martin/.workspace/p6/realerror/A.pm (A) line 11
in method r at /home/martin/.workspace/p6/realerror/A.pm (A) line 6
in block <unit> at -e line 1

WHEN set_private looks like this​:

 method set\_private\(A $a\) \{
     $\!private = $a;
 \}

But method !s seems to be broken now.

I dont get why :( i would expect this to work. :-(

In addition I think the error message is broken​: "No such private method
'!!private' for invocant of type 'B'" it was differently in 2016.11

Hi, what's the full code in A.pm and B.pm files?

@p6rt
Copy link
Author

p6rt commented Jul 6, 2017

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

@p6rt
Copy link
Author

p6rt commented Jul 6, 2017

From @zoffixznet

cat A.pm
class A { ... }

role R {
  has A $!private;

  method r {
  self!s;
  }

  method !s {
  $!private!s if $!private; # line 12
  say $.b;
  }

  method !private-method {
  say "priv method";
  }

  method public-method {
  self!private-method;
  }

  method set_private(A $a) {
  $!private = $a;
  }
}

class A does R {
  has Str $.b = 'secret';
};

cat B.pm
use v6;
use A;

class B does R {
  method b { self.r }
}

@p6rt
Copy link
Author

p6rt commented Jul 7, 2017

From martin@senfdax.de

cat A.pm
class A { ... }

role R {
  has A $!private;

  method r {
  self!s;
  }

  method !s {
  $!private!s if $!private; # line 12
  say $.b;
  }

  method !private-method {
  say "priv method";
  }

  method public-method {
  self!private-method;
  }

  method set_private(A $a) {
  $!private = $a;
  }
}

class A does R {
  has Str $.b = 'secret';
};

cat B.pm
use v6;
use A;

class B does R {
  method b { self.r }
}

Am 06.07.2017 um 15​:35 schrieb Zoffix Znet via RT​:

On Wed, 05 Jul 2017 09​:09​:48 -0700, martin@​senfdax.de wrote​:

Hi there,

this is crossposed in the perl6-users mailing list. Since noone stopped
me from assuming that this is a bug, i am going to open this now​:

Assuming those two files A.pm and B.pm.

The file A.pm contains a class A and a role R with a private-method and
a $!private member. (the files are in the end of the e-mail)

1) I am wondering why a role can all its private methods​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.public-method()'
priv method

2) but can't write its private members​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.set_private(A.new); $b.r'
No such private method '!!private' for invocant of type 'B'
in method set_private at /home/martin/.workspace/p6/realerror/A.pm
(A) line 24
in block <unit> at -e line 1

WHEN! the set_private looks like this​:

  method set\_private\(A $a\) \{
      self\!private = $a;
  \}

3) It seems to work (well, it gets a error a bit later in $b.r)​:

perl6 -I. -e 'use A; use B; my $b = B.new; $b.set_private(A.new); $b.r
'
P6opaque​: no such attribute '$!private' in type B when trying to get a
value
in method s at /home/martin/.workspace/p6/realerror/A.pm (A) line 11
in method s at /home/martin/.workspace/p6/realerror/A.pm (A) line 11
in method r at /home/martin/.workspace/p6/realerror/A.pm (A) line 6
in block <unit> at -e line 1

WHEN set_private looks like this​:

  method set\_private\(A $a\) \{
      $\!private = $a;
  \}

But method !s seems to be broken now.

I dont get why :( i would expect this to work. :-(

In addition I think the error message is broken​: "No such private method
'!!private' for invocant of type 'B'" it was differently in 2016.11

Hi, what's the full code in A.pm and B.pm files?

@p6rt p6rt added the Bug label Jan 5, 2020
@JJ
Copy link

JJ commented Dec 30, 2020

I've golfed it down to :

role R {
  has $!private;

  method !s {
      $!private if $!private;
  }

  method !private-method {
      say "priv method";
  }

  method public-method {
      self!private-method;
  }

  method set_private($a) {
      $!private = $a;
  }
}

class B does R {
  method b { self!s }
}

my $b = B.new();
$b.public-method();
$b.set_private("foo");
say $b.b;

and then the error disappears. The problem seems to lay in the strange construct $!private!s, which I don't really know if it was intended or not. The point is that this issue does not exist as formulated. I'll try to golf down that problem, and probably open it as a different issue.

@JJ
Copy link

JJ commented Dec 30, 2020

No need to golf it down. $!private!s is trying to call the private method s on the $!private object. So I golfed it down a bit too much.

@JJ
Copy link

JJ commented Dec 30, 2020

I'm starting to think this is a case of an LTA error more than any other thing. The problem is that, instead of just saying "Hey, A's method are private to this object, which is B" it's kind of mixing A and B. It should probably say "no such attribute on type A" (because it's private to B). If that's the case I can probably fix it.

@JJ
Copy link

JJ commented Dec 30, 2020

Maybe related to rakudo/rakudo#4127

@JJ
Copy link

JJ commented Dec 30, 2020

... And I leave the rabbit hole trying to look up where nqp::getattr is defined. I think it must be there, since it's not a Rakudo exception, but a NQP runtime exception, but that's way above my pay grade. Should be easy if anyone is familiar with that, I guess.

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

No branches or pull requests

2 participants