Re: Test fro overridden method

2006-12-30 Thread Richard Frith-Macdonald


On 29 Dec 2006, at 01:26, Fred Kiefer wrote:

Could somebody please verify that this method does what I expect it  
to do?
I need such a test within NSDocument. Here Apple takes special care  
that
if somebody has implemented the old interface methods for  
NSDocument in

a subclass, then these methods are actually called instead of the new
interface methods.

/*
 * Private helper method to check, if the method given via the  
selector sel

 * has been overridden in the current subclass.
 */
- (BOOL)_hasOverridden: (SEL)sel
{
  // The actual signature is not important as we wont call the  
methods.

  IMP meth1;
  IMP meth2;

  meth1 = [self methodForSelector: sel];
  meth2 = [[NSDocument class] instanceMethodForSelector: sel];

  return (meth1 != meth2);
}


I'm not sure what you mean by 'verify' ... but unless someone has  
overridden any of the three methods you use, I would expect the code  
to return 1 if the method for  _sel has been overridden, 0 otherwise.


You can bypass issues with those methods being overridden by calling  
the appropriate runtime functions, however if someone has overridden  
the methods they probably did so for a reason, and bypassing them  
could  also cause problems.  So while using the runtime directly can  
help, it can also (if less likely) cause problems.  I would guess it  
is less likely to cause problems than cure them, so runtime use is  
probably better, but it's by no means certain.


I suppose the most efficient implementation one could do would be  
something like ...


BOOL
GSObjCHasOverridden(Class baseClass, NSObject *instance, SEL selector)
{
  Class instanceClass = GSObjCClass(instance);

  if (instanceClass == baseClass
|| GSGetMethod(instanceClass, selector, YES. YES) == GSGetMethod 
(base, selector, YES. YES))

{
  return YES;
}
  return NO;
}

which might be a candidate for inclusion in GSObjCRuntime.[hm]

Of course, it might be worth being able to test overriding of class  
methods too, depending on whether you pass an instance or a class 


BOOL
GSObjCHasOverridden(Class baseClass, id object, SEL selector)
{
  if (GSObjCIsClass(object))
{
  if ((Class)object == baseClass
|| GSGetMethod((Class)object, selector, NO. YES) ==  
GSGetMethod(base, selector, NO. YES))

{
  return YES;
}
}
  else
{
  Class instanceClass = GSObjCClass(object);

  if (instanceClass == baseClass
|| GSGetMethod(instanceClass, selector, YES. YES) ==  
GSGetMethod(base, selector, YES. YES))

{
  return YES;
}
}
  return NO;
}






___
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev


Re: Test fro overridden method

2006-12-30 Thread Fred Kiefer
Richard Frith-Macdonald schrieb:
 
 On 29 Dec 2006, at 01:26, Fred Kiefer wrote:
 
 Could somebody please verify that this method does what I expect it to
 do?
 I need such a test within NSDocument. Here Apple takes special care that
 if somebody has implemented the old interface methods for NSDocument in
 a subclass, then these methods are actually called instead of the new
 interface methods.

 /*
  * Private helper method to check, if the method given via the
 selector sel
  * has been overridden in the current subclass.
  */
 - (BOOL)_hasOverridden: (SEL)sel
 {
   // The actual signature is not important as we wont call the methods.
   IMP meth1;
   IMP meth2;

   meth1 = [self methodForSelector: sel];
   meth2 = [[NSDocument class] instanceMethodForSelector: sel];

   return (meth1 != meth2);
 }
 
 I'm not sure what you mean by 'verify' ... but unless someone has
 overridden any of the three methods you use, I would expect the code to
 return 1 if the method for  _sel has been overridden, 0 otherwise.
 
 You can bypass issues with those methods being overridden by calling the
 appropriate runtime functions, however if someone has overridden the
 methods they probably did so for a reason, and bypassing them could 
 also cause problems.  So while using the runtime directly can help, it
 can also (if less likely) cause problems.  I would guess it is less
 likely to cause problems than cure them, so runtime use is probably
 better, but it's by no means certain.
 
 I suppose the most efficient implementation one could do would be
 something like ...
 
 BOOL
 GSObjCHasOverridden(Class baseClass, NSObject *instance, SEL selector)
 {
   Class instanceClass = GSObjCClass(instance);
 
   if (instanceClass == baseClass
 || GSGetMethod(instanceClass, selector, YES. YES) ==
 GSGetMethod(base, selector, YES. YES))
 {
   return YES;
 }
   return NO;
 }
 
 which might be a candidate for inclusion in GSObjCRuntime.[hm]
 
 Of course, it might be worth being able to test overriding of class
 methods too, depending on whether you pass an instance or a class 
 
 BOOL
 GSObjCHasOverridden(Class baseClass, id object, SEL selector)
 {
   if (GSObjCIsClass(object))
 {
   if ((Class)object == baseClass
 || GSGetMethod((Class)object, selector, NO. YES) ==
 GSGetMethod(base, selector, NO. YES))
 {
   return YES;
 }
 }
   else
 {
   Class instanceClass = GSObjCClass(object);
 
   if (instanceClass == baseClass
 || GSGetMethod(instanceClass, selector, YES. YES) ==
 GSGetMethod(base, selector, YES. YES))
 {
   return YES;
 }
 }
   return NO;
 }

Thank you very much for this code. This uses some fast but GNU runtime
specific functions. I will stick with my slower method of testing until
this implementation makes it into GSobjCRuntime and we also have an
abstraction that allows similar tests with the Apple runtime.

Cheers,
Fred


___
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev


Re: Test fro overridden method

2006-12-30 Thread Richard Frith-Macdonald


On 30 Dec 2006, at 16:09, Fred Kiefer wrote:


BOOL
GSObjCHasOverridden(Class baseClass, id object, SEL selector)
{
  if (GSObjCIsClass(object))
{
  if ((Class)object == baseClass
|| GSGetMethod((Class)object, selector, NO. YES) ==
GSGetMethod(base, selector, NO. YES))
{
  return YES;
}
}
  else
{
  Class instanceClass = GSObjCClass(object);

  if (instanceClass == baseClass
|| GSGetMethod(instanceClass, selector, YES. YES) ==
GSGetMethod(base, selector, YES. YES))
{
  return YES;
}
}
  return NO;
}


Thank you very much for this code. This uses some fast but GNU runtime
specific functions. I will stick with my slower method of testing  
until

this implementation makes it into GSobjCRuntime and we also have an
abstraction that allows similar tests with the Apple runtime.


Actually, it doesn't use ANY GNU runtime specific functions, it's  
entirely runtime independent code!


It uses functions from GSObjCRuntime.h and GSObjCRuntime.m ... which  
are wrappers round either GNU runtime functions or Apple runtime  
functions depending on which system you build.


The equivalent GNU runtime specific code would use object_is_class()  
rather than GSObjCIsClass() and would use class_get_instance_method()  
and class_get_class_method() rather than GSGetMethod()





___
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev


Re: Test fro overridden method

2006-12-30 Thread Fred Kiefer
Richard Frith-Macdonald schrieb:
 
 On 30 Dec 2006, at 16:09, Fred Kiefer wrote:
 
 BOOL
 GSObjCHasOverridden(Class baseClass, id object, SEL selector)
 {
   if (GSObjCIsClass(object))
 {
   if ((Class)object == baseClass
 || GSGetMethod((Class)object, selector, NO. YES) ==
 GSGetMethod(base, selector, NO. YES))
 {
   return YES;
 }
 }
   else
 {
   Class instanceClass = GSObjCClass(object);

   if (instanceClass == baseClass
 || GSGetMethod(instanceClass, selector, YES. YES) ==
 GSGetMethod(base, selector, YES. YES))
 {
   return YES;
 }
 }
   return NO;
 }

 Thank you very much for this code. This uses some fast but GNU runtime
 specific functions. I will stick with my slower method of testing until
 this implementation makes it into GSobjCRuntime and we also have an
 abstraction that allows similar tests with the Apple runtime.
 
 Actually, it doesn't use ANY GNU runtime specific functions, it's
 entirely runtime independent code!
 
 It uses functions from GSObjCRuntime.h and GSObjCRuntime.m ... which are
 wrappers round either GNU runtime functions or Apple runtime functions
 depending on which system you build.
 
 The equivalent GNU runtime specific code would use object_is_class()
 rather than GSObjCIsClass() and would use class_get_instance_method()
 and class_get_class_method() rather than GSGetMethod()
 

Oops, thank you for pointing this out. I should have checked in the code
before making this statement. The used functions are in the Additions of
base and would thereby be valid to be used in gui. Still I think this
function looks too serious to be thrown into a gui class as a helper. It
would confuse people like me. :-)

Cheers,
Fred



___
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev


Test fro overridden method

2006-12-28 Thread Fred Kiefer
Could somebody please verify that this method does what I expect it to do?
I need such a test within NSDocument. Here Apple takes special care that
if somebody has implemented the old interface methods for NSDocument in
a subclass, then these methods are actually called instead of the new
interface methods.

/*
 * Private helper method to check, if the method given via the selector sel
 * has been overridden in the current subclass.
 */
- (BOOL)_hasOverridden: (SEL)sel
{
  // The actual signature is not important as we wont call the methods.
  IMP meth1;
  IMP meth2;

  meth1 = [self methodForSelector: sel];
  meth2 = [[NSDocument class] instanceMethodForSelector: sel];

  return (meth1 != meth2);
}

If the code stays that simple, I might even make a macro of it.

Cheers,
Fred


___
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev