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

Possible bug in Perl 6 OO #6685

Closed
p6rt opened this issue Jun 4, 2018 · 6 comments
Closed

Possible bug in Perl 6 OO #6685

p6rt opened this issue Jun 4, 2018 · 6 comments

Comments

@p6rt
Copy link

p6rt commented Jun 4, 2018

Migrated from rt.perl.org#133246 (status was 'rejected')

Searchable as RT133246$

@p6rt
Copy link
Author

p6rt commented Jun 4, 2018

From richard.hogaboom@gmail.com

Attached is an executable file that demos a possible Perl 6 OO bug if
attributes and method names are the same.  This includes some compile
time errors and an infinite loop.

--
Richard A Hogaboom
16 Alprilla Farm Road
Hopkinton, MA 01748-1922
richard.hogaboom@​gmail.com
www.linkedin.com/in/richardhogaboom/
https://plus.google.com/+RichardHogaboom
https://github.com/rahogaboom
M508-330-3775

@p6rt
Copy link
Author

p6rt commented Jun 4, 2018

From richard.hogaboom@gmail.com

# Richard Hogaboom
# richard.hogaboom@​gmail.com

# Fedora 28
# Perl 6 2018.04
# uname -a
# Linux new-host-3 4.16.12-300.fc28.x86_64 #​1 SMP Fri May 25 21​:13​:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

# in Perl 6 OO if you have in a class an attribute name and a method name that are the same,
# some errors may result or not - including compile time errors and an infinite loop. just
# comment in the various examples one by one to run them individually.

use v6;

=begin pod
# EXAMPLE 1
# this works

class Address {
  has $.var is rw;
}

my $addr = Address.new;
$addr.var = 'VAR';
say $addr.var;
=end pod

=begin pod
# EXAMPLE 2
# this works

class Address {
  has $.var is rw;

  multi method var() {
  return $!var;
  }

  multi method var(Str $v) {
  $!var = $v;
  }
}

my $addr = Address.new;
$addr.var('VAR');
say $addr.var();
=end pod

=begin pod
# EXAMPLE 3
# adding a method of the same name as the attribute gives​:
# Cannot modify an immutable Str (Nil)
# in block <unit> at t.p6 line 66

class Address {
  has $.var is rw;

  method var() {
  }
}

my $addr = Address.new;
$addr.var = 'VAR';
say $addr.var;

# is there a general prohibition on having an attribute and an explicit method of the same name?
=end pod

=begin pod
# EXAMPLE 4
# adding a return statement in the var() method gives a hang.
# using top shows the moar process at 100% CPU.

class Address {
  has $.var is rw;

  method var() {
  return $.var;
  }
}

my $addr = Address.new;
$addr.var = 'VAR';
say $addr.var;

# why does just adding a return statement eliminate the compile error? and hang?
# either this should not compile or a run time error should occur, not an infinite loop.
# adding 'multi' to 'method var() {' above does not help.
=end pod

=begin pod
# EXAMPLE 5
# changing only $.var to $!var in the var() method gives​:
# Cannot assign to a readonly variable or a value
# in block <unit> at t.p6 line 109

class Address {
  has $.var is rw;

  method var() {
  return $!var;
  }
}

my $addr = Address.new;
$addr.var = 'VAR';
say $addr.var;

# this eliminates the infinite loop , but returns to the previous readonly variable msg.
=end pod

# all this seems a caution against using the same name as an attribute and explicit method name,
# but shouldn't there be some type of prohibition/warning?

@p6rt
Copy link
Author

p6rt commented Jun 9, 2018

From @zoffixznet

On Mon, 04 Jun 2018 07​:31​:40 -0700, richard.hogaboom@​gmail.com wrote​:

Attached is an executable file that demos a possible Perl 6 OO bug if
attributes and method names are the same.  This includes some compile
time errors and an infinite loop.

Thanks for the report, but there's no bug here.

The `has $.foo` attribute syntax is just a shorthand for writing `has $!foo; method foo { $!foo }`.
In other words, the compiler auto-generated an accessor method for you.

When you use `$.foo` syntax inside a method, it's a shorthand for `self.foo`; in other words, it's a
method call.

If you define a method with the same name as the attribute, then it signals to the compiler that you chose
to take care of accessor method yourself.

Also, to return a writeable container, you need to either use `return-rw` instead of plain `return` when
using explicit return, or apply the `is rw` trait to the method, when using implicit return​:

  method var1() is rw { return $!var }
  method var2() { return-rw $!var }

With that knowledge, you can see why the failing examples fail​:

* EXAMPLE 3​: You defined a method with the same name as attribute, so it'll function as the accessor. The body
  of that method is empty, so it returns `Nil` and hence the error about trying to assign to `Nil`
* EXAMPLE 4​: Again, you defined your own accessor, but now you're also using `$.var` syntax inside, so the method
  infiniloops calling itself over and over. Hence the hang.
* EXAMPLE 5​: You've used `return` instead of `return-rw`, so only a readonly value is returned instead of a
  writable container. Hence the error

but shouldn't there be some type of prohibition/warning?

No, as it's perfectly fine to declare your own accessors. Of course, writing `has $.foo` instead of `has $!foo` is
pointless, in that case, but it serves as a hint to the programmer that it's a public attribute, so I don't think
warning about that is appropriate.

@p6rt
Copy link
Author

p6rt commented Jun 9, 2018

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

@p6rt
Copy link
Author

p6rt commented Jun 9, 2018

@zoffixznet - Status changed from 'open' to 'rejected'

@p6rt p6rt closed this as completed Jun 9, 2018
@p6rt
Copy link
Author

p6rt commented Jun 9, 2018

From @zoffixznet

On Sat, 09 Jun 2018 05​:33​:04 -0700, cpan@​zoffix.com wrote​:

when
using implicit return​:

method var1() is rw { return $!var }
method var2() { return-rw $!var }

Correction, that should be​:

  method var1() is rw { $!var }
  method var2() { return-rw $!var }

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