[prev in list] [next in list] [prev in thread] [next in thread] 

List:       groovy-jsr
Subject:    Re: [groovy-jsr] Re: [groovy-dev] Changing the signature of invokeMethod()
From:       Jochen Theodorou <blackdrag () gmx ! org>
Date:       2005-10-10 22:55:33
Message-ID: 434AF165.5040208 () gmx ! org
[Download RAW message or body]

John Rose schrieb:
[...]
>>> This standard mechanism should not break encapsulation barriers, if  
>>> it's going to be a trusted player on peoples' app. stacks.
>>
>> as long as the method is not called directly from the object as it would 
>> in Java we have to deal with encapsulation barriers.
> 
> There are many use cases (perhaps most) where encapsulation barriers do 
> not matter, because everything is public.

agreed, but there enough where this does

> As you say, restricted-access calls (e.g., within a package) need to be 
> implemented by Groovy for compatibility with Java.
> What I'm objecting to is routing restricted access calls through a 
> common API the same as calls from arbitrary callers.

That's what I ment with "another merthod for MetaClass". I thought about:

invokeMethod(Object callObject, Object calledObject, String methodName, 
Object[] args)

and variants.. (maybe the variants can be unified somehow)

class Foo {
   def bar(){
     "2".toString()
   }
}

-->

class Foo {
   def bar(){
     invokeMethod(this,"2","toString", new Object[]{});
   }
}

and:

invokeMethod(Object calledObject, String methodName, Object[] args) {
   invokeMethod(null, calledObject, methodName, args)
}

but these code parts are not from GroovyObject, they are from a possible 
implementation on the 
ScriptByteCodeAdapter/InvokerHelper/Invoker/MetaClass chain

but as I think about it... this "this" I used above is not the Java 
this... it will not work as I thought that way... maybe "this" (as in 
Java) and the class.

Reson is subclassing, it would change "this". For access we basically 
need to know which class tries to access something, for some other 
things I talked with MrG it would be nioce to have a reaction based on 
the instance that made the call... of course that changes its type when 
subclassing.

so it would be:

invokeMethod(Foo.class,this,"2","toString", new Object[]{});

instead and

invokeMethod(Object calledObject, String methodName, Object[] args) {
   invokeMethod(null, null, calledObject, methodName, args)
}

>>> There should be a "skeleton key" adapter which (with suitable  
>>> permission checks) provides the same dynamic invoke API, pointed at  
>>> the non-public parts of a class.
>>
>> ok, let's say another method in MetaClass
> 
> I suppose there would be some variation of GroovyObjectSupport which 
> would call the variant MetaClass methods.

GroovyObject's method is called *after* MetaClass has ensured there is 
nothing for the object in MetaClass.

> (MetaClass is quite large; does it have too many jobs already?)

maybe. A new Thread about this started today.

>>> It should be kept separate from the standard mechanism.
>>
>> what about the cases where private is visible by default?
> 
> The safest way to access a private is directly from the owning class's 
> bytecodes.
 > That way there are no doubtful uses of reflection, which might "leak"
 > private methods to the world.

but not doable for methods since we have to do the dispatching manually.

> It seems to me that that in order to do this, we need a little more 
> static analysis.

I am unsure about fields, and properties, I think it's not always 
working as it should... for example:

class X{
   private x=1
   private getX(){2}

   def foo() {
     def bar = x
   }
}

currently the field is choosen and afaik the method getX should be 
choosen. These rules need to be described somewhere or it is useless to 
discuss them since not every one knows them all and not every one knows 
the same rules.

> And there are bound to be implementation restrictions, at least at first.
> For example, there are special problems with private overloaded 
> functions taking dynamic arguments.

private function are a general problem, because as I said we have to do 
dispatching by ourselfs. No static analysis will call the correct method 
here in all cases:

class Y{
   private foo(Object o){}
   private foo(String s){}
[...]
     def x = new AGroovyClass();
     foo(x.getAnObject())
[...]

because if getAnObject returns String, foo(String) should be called, not 
foo(Object) just because getAnObject is declared to return Object. And 
that's onw of the more easy cases.

>>> It would simplify our lives if the default dynamic invoke wrapper  
>>> dealt only with public methods.
>>
>>> Then the GroovyObject API would not need to "know" about access level
>>
>>> distinctions.
>>
>> it can't handle only public, it has also to call protected and private 
>> somehow. because for the same class we have to do method invokes too. 
>> And for subclasses and for classes from the same package. And it's not 
>> only methods, it's fields too:
>>
>> class Foo {
>>   private bar =1
>>   public getBar(){bar}
>> }
> 
> In this case, a static analysis can guide the generation of direct 
> bytecode access to bar.

agreed

> If 'bar' is lexically scoped, there should be no big problem.

I gave another example above.

>>> The middle ground between private and public, of protected and  
>>> package-private access, is probably best handled by static typing,  
>>> following Java rules.
>>
>> what do you mean with "middle ground"?
> 
> (Sorry, failed metaphor.)  I meant what we've been talking about,
> the group of use cases "between" than the easiest and most dangerous, #2 
> on this list:
>  1. all names are public (the easy, common case, no encapsulation 
> boundaries)
>  2. some names non-public, but access follows Java rules (what I want to 
> handle statically)
>  3. completely disregard encapsulation boundaries (super-user gets a 
> "skeleton key" to any object at all)

static typing is no solution. look at my method example. I don't see how 
groovy should ever be able to do, see example Y. Another example:

class Z{
[...]
def a = b.c

maybe we know the type of b, but in general we can't. So there is always 
a possibility that c is a field/property of an class with the package or 
something like that. Same for private. Following the java rules we have 
to access c if b is of class Z or a subclass of it. so list item 2 can't 
be done statically in general

item #1 is... nothing for a Java programer. I'm sure I can program 
wihtout private... somehow... but it's really nice to have that and I do 
not really want to miss it. And how are java objects handled? I mean 
even if we onyl allow public in groovy, we still have to call method on 
object from the java-Api

item #3 is kind of like it is now.


bye blackdrag

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic