Conforming to a protocol
Hi, I was wondering if there is any way to formally indicate a MacRuby class conforms to an Objective-C protocol. I encountered some code that uses conformsToProtocol: instead of respondsToSelector: as a check before invoking delegate methods, and the only way I could get a delegate written in MacRuby to work was to create an Objective-C class with the same name and specify the required protocols in the interface declaration there. Thanks, Martijn
I don't have an example of a class that uses conformsToProtocol: on the delegate, so I can't give you a code example, but I would try to override the conformsToProtocol: class and instance methods and return true for those you support. On 15 nov 2010, at 00:15, Martijn Walraven wrote:
Hi,
I was wondering if there is any way to formally indicate a MacRuby class conforms to an Objective-C protocol. I encountered some code that uses conformsToProtocol: instead of respondsToSelector: as a check before invoking delegate methods, and the only way I could get a delegate written in MacRuby to work was to create an Objective-C class with the same name and specify the required protocols in the interface declaration there.
Thanks,
Martijn _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
I actually tried this, but the problem seems to be that Protocol is not a true class. So if I try to do anything with the protocol parameter from MacRuby, I get an error: *** NSInvocation: warning: object 0x7fff71192488 of class 'Protocol' does not implement methodSignatureForSelector: -- trouble ahead *** NSInvocation: warning: object 0x7fff71192488 of class 'Protocol' does not implement doesNotRecognizeSelector: -- abort Even just comparing it to another protocol object using protocol == Protocol.protocolWithName('...') leads to the same result. Any ideas as to how this could be made to work? On Nov 16, 2010, at 19:59 , Eloy Duran wrote:
I don't have an example of a class that uses conformsToProtocol: on the delegate, so I can't give you a code example, but I would try to override the conformsToProtocol: class and instance methods and return true for those you support.
On 15 nov 2010, at 00:15, Martijn Walraven wrote:
Hi,
I was wondering if there is any way to formally indicate a MacRuby class conforms to an Objective-C protocol. I encountered some code that uses conformsToProtocol: instead of respondsToSelector: as a check before invoking delegate methods, and the only way I could get a delegate written in MacRuby to work was to create an Objective-C class with the same name and specify the required protocols in the interface declaration there.
Thanks,
Martijn _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
Can you provide a simple failing example? On Nov 17, 2010, at 9:26 AM, Martijn Walraven wrote:
I actually tried this, but the problem seems to be that Protocol is not a true class. So if I try to do anything with the protocol parameter from MacRuby, I get an error:
*** NSInvocation: warning: object 0x7fff71192488 of class 'Protocol' does not implement methodSignatureForSelector: -- trouble ahead *** NSInvocation: warning: object 0x7fff71192488 of class 'Protocol' does not implement doesNotRecognizeSelector: -- abort
Even just comparing it to another protocol object using protocol == Protocol.protocolWithName('...') leads to the same result.
Any ideas as to how this could be made to work?
On Nov 16, 2010, at 19:59 , Eloy Duran wrote:
I don't have an example of a class that uses conformsToProtocol: on the delegate, so I can't give you a code example, but I would try to override the conformsToProtocol: class and instance methods and return true for those you support.
On 15 nov 2010, at 00:15, Martijn Walraven wrote:
Hi,
I was wondering if there is any way to formally indicate a MacRuby class conforms to an Objective-C protocol. I encountered some code that uses conformsToProtocol: instead of respondsToSelector: as a check before invoking delegate methods, and the only way I could get a delegate written in MacRuby to work was to create an Objective-C class with the same name and specify the required protocols in the interface declaration there.
Thanks,
Martijn _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-). In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object. I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say. Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-). -- Thibault Martin-Lagardette On Nov 17, 2010, at 09:26, Martijn Walraven wrote:
I actually tried this, but the problem seems to be that Protocol is not a true class. So if I try to do anything with the protocol parameter from MacRuby, I get an error:
*** NSInvocation: warning: object 0x7fff71192488 of class 'Protocol' does not implement methodSignatureForSelector: -- trouble ahead *** NSInvocation: warning: object 0x7fff71192488 of class 'Protocol' does not implement doesNotRecognizeSelector: -- abort
Even just comparing it to another protocol object using protocol == Protocol.protocolWithName('...') leads to the same result.
Any ideas as to how this could be made to work?
On Nov 16, 2010, at 19:59 , Eloy Duran wrote:
I don't have an example of a class that uses conformsToProtocol: on the delegate, so I can't give you a code example, but I would try to override the conformsToProtocol: class and instance methods and return true for those you support.
On 15 nov 2010, at 00:15, Martijn Walraven wrote:
Hi,
I was wondering if there is any way to formally indicate a MacRuby class conforms to an Objective-C protocol. I encountered some code that uses conformsToProtocol: instead of respondsToSelector: as a check before invoking delegate methods, and the only way I could get a delegate written in MacRuby to work was to create an Objective-C class with the same name and specify the required protocols in the interface declaration there.
Thanks,
Martijn _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
Thanks for opening a ticket and describing the issue so well! I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs? Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint). I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment? On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-).
In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object.
I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say.
Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-).
-- Thibault Martin-Lagardette
These structures are currently handled by Foundation's BridgeSupport file (/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.bridgesupport) <struct name='NSPoint' type64='{CGPoint="x"d"y"d}' type='{_NSPoint="x"f"y"f}'/> <struct name='NSRange' type64='{_NSRange="location"Q"length"Q}' type='{_NSRange="location"I"length"I}'/> It's not very humanly readable, but MacRuby understands what this means, and then knows NSPoint is a structure :-). However, just for proving myself wrong, there IS a Protocol Obj-C objet ( see http://opensource.apple.com/source/objc4/objc4-437.1/runtime/Protocol.h ). But I think my point stands, as I do think what is returned is the C struct, not the class. I think Laurent might know a little better though :-) -- Thibault Martin-Lagardette On Nov 17, 2010, at 12:19, Martijn Walraven wrote:
Thanks for opening a ticket and describing the issue so well!
I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs?
Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint).
I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment?
On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-).
In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object.
I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say.
Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-).
-- Thibault Martin-Lagardette
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
Regardless of the current state, having a real Protocol class and objects that you can use to check against should be the goal. Let's discuss this further on the ticket from now on, for completeness sake. On Nov 17, 2010, at 12:44 PM, Thibault Martin-Lagardette wrote:
These structures are currently handled by Foundation's BridgeSupport file (/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.bridgesupport) <struct name='NSPoint' type64='{CGPoint="x"d"y"d}' type='{_NSPoint="x"f"y"f}'/> <struct name='NSRange' type64='{_NSRange="location"Q"length"Q}' type='{_NSRange="location"I"length"I}'/> It's not very humanly readable, but MacRuby understands what this means, and then knows NSPoint is a structure :-).
However, just for proving myself wrong, there IS a Protocol Obj-C objet ( see http://opensource.apple.com/source/objc4/objc4-437.1/runtime/Protocol.h ). But I think my point stands, as I do think what is returned is the C struct, not the class. I think Laurent might know a little better though :-)
-- Thibault Martin-Lagardette
On Nov 17, 2010, at 12:19, Martijn Walraven wrote:
Thanks for opening a ticket and describing the issue so well!
I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs?
Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint).
I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment?
On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-).
In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object.
I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say.
Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-).
-- Thibault Martin-Lagardette
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
In case anyone needs it in the meantime, here is a working implementation of conformsToProtocol: def conformsToProtocol(protocol) supported = %w( AProtocol SomeOtherProtocol YetAnotherProtocol ).map {|name| Protocol.protocolWithName name} # List the protocols you want to conform to between the parns supported.any? {|candidate| protocol.isEqual candidate } or super end The reason this works is because Protocol *is* a real class, but it's derived from a base class different from NSObject. Obviously we'll want a better solution for MacRuby, but this will work in the meantime. — Chuck On Wed, Nov 17, 2010 at 4:42 AM, Eloy Duran <eloy.de.enige@gmail.com> wrote:
Regardless of the current state, having a real Protocol class and objects that you can use to check against should be the goal. Let's discuss this further on the ticket from now on, for completeness sake. On Nov 17, 2010, at 12:44 PM, Thibault Martin-Lagardette wrote:
These structures are currently handled by Foundation's BridgeSupport file (/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.bridgesupport) <struct name='NSPoint' type64='{CGPoint="x"d"y"d}' type='{_NSPoint="x"f"y"f}'/> <struct name='NSRange' type64='{_NSRange="location"Q"length"Q}' type='{_NSRange="location"I"length"I}'/> It's not very humanly readable, but MacRuby understands what this means, and then knows NSPoint is a structure :-). However, just for proving myself wrong, there IS a Protocol Obj-C objet ( see http://opensource.apple.com/source/objc4/objc4-437.1/runtime/Protocol.h ). But I think my point stands, as I do think what is returned is the C struct, not the class. I think Laurent might know a little better though :-) -- Thibault Martin-Lagardette
On Nov 17, 2010, at 12:19, Martijn Walraven wrote:
Thanks for opening a ticket and describing the issue so well! I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs? Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint). I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment? On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-). In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object. I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say. Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-). -- Thibault Martin-Lagardette
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
I commented the #999 ticket, I believe there is a way to make MacRuby classes automatically conform to protocols (once all required methods are implemented). Let's try to get that done for the upcoming release :) Laurent On Nov 20, 2010, at 2:28 PM, Charles Steinman wrote:
In case anyone needs it in the meantime, here is a working implementation of conformsToProtocol:
def conformsToProtocol(protocol) supported = %w( AProtocol SomeOtherProtocol YetAnotherProtocol ).map {|name| Protocol.protocolWithName name} # List the protocols you want to conform to between the parns supported.any? {|candidate| protocol.isEqual candidate } or super end
The reason this works is because Protocol *is* a real class, but it's derived from a base class different from NSObject. Obviously we'll want a better solution for MacRuby, but this will work in the meantime.
— Chuck
On Wed, Nov 17, 2010 at 4:42 AM, Eloy Duran <eloy.de.enige@gmail.com> wrote:
Regardless of the current state, having a real Protocol class and objects that you can use to check against should be the goal. Let's discuss this further on the ticket from now on, for completeness sake. On Nov 17, 2010, at 12:44 PM, Thibault Martin-Lagardette wrote:
These structures are currently handled by Foundation's BridgeSupport file (/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.bridgesupport) <struct name='NSPoint' type64='{CGPoint="x"d"y"d}' type='{_NSPoint="x"f"y"f}'/> <struct name='NSRange' type64='{_NSRange="location"Q"length"Q}' type='{_NSRange="location"I"length"I}'/> It's not very humanly readable, but MacRuby understands what this means, and then knows NSPoint is a structure :-). However, just for proving myself wrong, there IS a Protocol Obj-C objet ( see http://opensource.apple.com/source/objc4/objc4-437.1/runtime/Protocol.h ). But I think my point stands, as I do think what is returned is the C struct, not the class. I think Laurent might know a little better though :-) -- Thibault Martin-Lagardette
On Nov 17, 2010, at 12:19, Martijn Walraven wrote:
Thanks for opening a ticket and describing the issue so well! I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs? Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint). I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment? On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-). In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object. I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say. Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-). -- Thibault Martin-Lagardette
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
I just pushed a fix for this which checks if the class, or instance, implements the required methods for the protocol given to conformsToProtocol:. Please give it a try :) Eloy On 22 nov 2010, at 02:53, Laurent Sansonetti wrote:
I commented the #999 ticket, I believe there is a way to make MacRuby classes automatically conform to protocols (once all required methods are implemented).
Let's try to get that done for the upcoming release :)
Laurent
On Nov 20, 2010, at 2:28 PM, Charles Steinman wrote:
In case anyone needs it in the meantime, here is a working implementation of conformsToProtocol:
def conformsToProtocol(protocol) supported = %w( AProtocol SomeOtherProtocol YetAnotherProtocol ).map {|name| Protocol.protocolWithName name} # List the protocols you want to conform to between the parns supported.any? {|candidate| protocol.isEqual candidate } or super end
The reason this works is because Protocol *is* a real class, but it's derived from a base class different from NSObject. Obviously we'll want a better solution for MacRuby, but this will work in the meantime.
— Chuck
On Wed, Nov 17, 2010 at 4:42 AM, Eloy Duran <eloy.de.enige@gmail.com> wrote:
Regardless of the current state, having a real Protocol class and objects that you can use to check against should be the goal. Let's discuss this further on the ticket from now on, for completeness sake. On Nov 17, 2010, at 12:44 PM, Thibault Martin-Lagardette wrote:
These structures are currently handled by Foundation's BridgeSupport file (/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.bridgesupport) <struct name='NSPoint' type64='{CGPoint="x"d"y"d}' type='{_NSPoint="x"f"y"f}'/> <struct name='NSRange' type64='{_NSRange="location"Q"length"Q}' type='{_NSRange="location"I"length"I}'/> It's not very humanly readable, but MacRuby understands what this means, and then knows NSPoint is a structure :-). However, just for proving myself wrong, there IS a Protocol Obj-C objet ( see http://opensource.apple.com/source/objc4/objc4-437.1/runtime/Protocol.h ). But I think my point stands, as I do think what is returned is the C struct, not the class. I think Laurent might know a little better though :-) -- Thibault Martin-Lagardette
On Nov 17, 2010, at 12:19, Martijn Walraven wrote:
Thanks for opening a ticket and describing the issue so well! I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs? Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint). I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment? On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-). In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object. I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say. Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-). -- Thibault Martin-Lagardette
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
I fixed a bug in your fix and improved it, so that we will automatically register the given protocol in the class, therefore the second call to conformsToProtocol: will be faster. Please give it a try guys, it should be available in tonight's nightly build. Laurent On Nov 22, 2010, at 3:12 PM, Eloy Duran wrote:
I just pushed a fix for this which checks if the class, or instance, implements the required methods for the protocol given to conformsToProtocol:. Please give it a try :)
Eloy
On 22 nov 2010, at 02:53, Laurent Sansonetti wrote:
I commented the #999 ticket, I believe there is a way to make MacRuby classes automatically conform to protocols (once all required methods are implemented).
Let's try to get that done for the upcoming release :)
Laurent
On Nov 20, 2010, at 2:28 PM, Charles Steinman wrote:
In case anyone needs it in the meantime, here is a working implementation of conformsToProtocol:
def conformsToProtocol(protocol) supported = %w( AProtocol SomeOtherProtocol YetAnotherProtocol ).map {|name| Protocol.protocolWithName name} # List the protocols you want to conform to between the parns supported.any? {|candidate| protocol.isEqual candidate } or super end
The reason this works is because Protocol *is* a real class, but it's derived from a base class different from NSObject. Obviously we'll want a better solution for MacRuby, but this will work in the meantime.
— Chuck
On Wed, Nov 17, 2010 at 4:42 AM, Eloy Duran <eloy.de.enige@gmail.com> wrote:
Regardless of the current state, having a real Protocol class and objects that you can use to check against should be the goal. Let's discuss this further on the ticket from now on, for completeness sake. On Nov 17, 2010, at 12:44 PM, Thibault Martin-Lagardette wrote:
These structures are currently handled by Foundation's BridgeSupport file (/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.bridgesupport) <struct name='NSPoint' type64='{CGPoint="x"d"y"d}' type='{_NSPoint="x"f"y"f}'/> <struct name='NSRange' type64='{_NSRange="location"Q"length"Q}' type='{_NSRange="location"I"length"I}'/> It's not very humanly readable, but MacRuby understands what this means, and then knows NSPoint is a structure :-). However, just for proving myself wrong, there IS a Protocol Obj-C objet ( see http://opensource.apple.com/source/objc4/objc4-437.1/runtime/Protocol.h ). But I think my point stands, as I do think what is returned is the C struct, not the class. I think Laurent might know a little better though :-) -- Thibault Martin-Lagardette
On Nov 17, 2010, at 12:19, Martijn Walraven wrote:
Thanks for opening a ticket and describing the issue so well! I'm not sure how this should be solved, but I was wondering how things currently work for other C structs like NSRect or NSPoint. Are these handled as special cases, or is there a more general way to deal with C structs? Would it make sense to think about somehow mapping C structs to the Ruby Struct class, or maybe a special CStruct class? It would be nice if this at least offered a way to perform equality checks (==, eql?, equals?). For structs that have defined attributes it would be great if this allowed getting and setting attribute values (similar to what you can do with NSRect and NSPoint). I might be totally off, so maybe someone who knows more about the internals of MacRuby can comment? On Nov 17, 2010, at 11:33 , Thibault Martin-Lagardette wrote:
This is because protocols, in the Obj-C runtime, are not Obj-C objets per say, they are C structs. +protocolWithName returns an (id) (aka obj-c objet), but the actual returned pointer is just a pointer to a C struct, which causes the runtime to issue those warnings. It says "Hey, this method returned an objet, but it doesn't look like one!". Which is expected, but this should be improved. While it is true that in the Obj-C runtime, classes and objects are C structs too, they are obviously not the same kind of structures, which is why it doesn't work :-). In MacRuby, `Protocol` IS a real Obj-C objet, but not what the +protocolWithName method returns. This means that whatever you do with the returned valiue, it will crash, because it is not a real objet, and thus does not respond to any message. This also means that you cannot even do something like that: Protocol.protocolWithName("NSCoding") == Protocol.protocolWithName("NSCoding") Simply because doing this will call the `#==` method on the left-most value, which is a C struct for a protocol, and not an Obj-C object. I created https://www.macruby.org/trac/ticket/999 , related to protocols. Please be aware that the attached patch still does not make it possible to override conformsToProtocol:, because calling `#==` on non-objets will crash, which is why I think MacRuby could handle Protocols a little better, right now I'm not sure it's "usable" per say. Sorry if I do repeat myself a little, but I want to make sure you understand why this does not work yet, and what you can and cannot do with protocols as of today :-). -- Thibault Martin-Lagardette
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
participants (5)
-
Charles Steinman
-
Eloy Duran
-
Laurent Sansonetti
-
Martijn Walraven
-
Thibault Martin-Lagardette