[ 
https://issues.apache.org/jira/browse/GROOVY-11627?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17951052#comment-17951052
 ] 

Jochen Theodorou edited comment on GROOVY-11627 at 5/15/25 10:47 AM:
---------------------------------------------------------------------

[~emilles]
Long explanation:
{code:Java}
class A {
  def foo() {bar()}
}
class B extends A {
  def bar(){1}
}

assert new B().foo() ==  1
{code}
This means bar becomes callable if we work on an instance that implements 
bar(). The problem now comes from bar() not only being valid for a method bar 
that takes no arguments. It could be with varargs. But imagine bar would have 
an argument, then there are many many more possible matches. Let's say we have 
bar("m") and in B we have the public method bar(Object) and bar(String). Well, 
it is easy, we then call bar(String) as per "normal" method dispatch. But what 
if bar(String) is private and bar(Object) is not? If private methods are 
implementation detail, then this means they should not be visible to calls made 
from A, right? But to calls from B they must. But then again any class was 
supposed to be able to call a private method on B like a public method as long 
as the instance is exactly B. This would say it must be possible to call the 
private method from A. 

The whole thing looks maybe a bit strange, but think of this without public and 
private. Then the way Groovy does method dispatch means, any subclass can 
provide a more specific method causing that method been used instead. Example:
{code:Java}
class A {
  def dispatch(x){m(x)}
  def m(x) {"object case"}
}
class B extends A {
  def m(String x) {"string case"}
}

def a = new A()
assert a.dispatch(null) == "object case"
assert a.m(null)  == "object case"
assert a.dispatch("string")== "object case"
assert a.m("string")  == "object case"

def b = new B()
assert b.dispatch(null) == "object case"
assert b.m(null)  == "object case"
assert b.dispatch("string") == "string case"
assert b.m("string")  == "string case"
{code}

I hope that explains use and problem a bit. It should be clear that this is no 
feature for static compilation.


was (Author: blackdrag):
[~emilles]
Long explanation:
{code:Java}
class A {
  def foo() {bar()}
}
class B extends A {
  def bar(){1}
}

assert new B().foo() ==  1
{code}
This means bar becomes callable if we work on an instance that implements 
bar(). The problem now comes from bar() not only being valid for a method bar 
that takes no arguments. It could be with varargs. But imagine bar would have 
an argument, then there are many many more possible matches. Let's say we have 
bar("m") and in B we have the public method bar(Object) and bar(String). Well, 
it is easy, we then call bar(String) as per "normal" method dispatch. But what 
if bar(String) is private and bar(Object) is not? If private methods are 
implementation detail, then this means they should not be visible to calls made 
from A, right? But to calls from B they must. But then again any class was 
supposed to be able to call a private method on B like a public method as long 
as the instance is exactly B. This would say it must be possible to call the 
private method from A. 

The whole thing looks maybe a bit strange, but think of this without public and 
private. Then the way Groovy does method dispatch means, any subclass can 
provide a more specific method causing that method been used instead. Example:
{code:Java}
class A {
  def dispatch(x){m(x)}
  def m(x) {"object case"}
}
class B extends A {
  def m(String x) {"string case"}
}

def a = new A()
assert a.dispatch(null)c == "object case"
assert a.m(null)  == "object case"
assert a.dispatch("string")== "object case"
assert a.m("string")  == "object case"

def b = new B()
assert b.dispatch(null) == "object case"
assert b.m(null)  == "object case"
assert a.dispatch("string") == "string case"
assert b.m("string")  == "string case"
{code}

I hope that explains use and problem a bit. It should be clear that this is no 
feature for static compilation.

> Compile Error when private and public functions use same name in compile 
> static mode
> ------------------------------------------------------------------------------------
>
>                 Key: GROOVY-11627
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11627
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Static compilation
>    Affects Versions: 5.0.0-alpha-12
>            Reporter: Saravanan
>            Assignee: Eric Milles
>            Priority: Minor
>
> When I define a class in Groovy with 2 methods with the same name, one 
> private and one public, I get this error during static compilation
> {quote}Mixing private and public/protected methods of the same name causes 
> multimethods to be disabled and is forbidden to avoid surprising behaviour. 
> Renaming the private methods will solve the problem.
> {quote}
> I understand the need for multi methods and dispatching with runtime types, 
> but how can I disable this behaviour? I am using @CompileStatic and it still 
> hits this error
> Per Jochen
> {quote}CompileStatic does not support multi methods, so I totally agree that
> this message should not appear for static compiled classes.
> {quote}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to