delegates in ruby explained from a Cocoa developer background - ruby

I really hope someone can answer this one. I think I am definitely not the only one confused about this and I wasn't able to find anything that clearly explains this concept.
My understanding of the delegation pattern comes from studying the Cocoa framework. To me, the Cocoa implementation is very clear. But I am having a very hard time understanding it in Ruby (standard library's Delegator, SimpleDelegator vs. ActiveSupport's Delegate). It makes little sense to me. Mostly because one is type safe the other is duck type. You can see my point already, but allow me to expand... Here is my summary of how to use the delegate pattern in Cocoa:
Our "ingredients" are: 2 classes, A and B and a protocol, which is Cocoa for a pre-defined set of methods to use for delegation.
The implementation of the pattern is basically as follows:
A defines the set of methods to delegate to B.
B's delegate is set to be A
=> B can now call delegated methods like so: #delegate.send(a_delegated_method)
What I am not tying together is the fact that Ruby uses duck typing, so you can send any method call to any object, right? So using the pattern I just explained, as long as the 2 objects are in the same domain you can say while in A #b.send(:a_delegated_method) and vice versa while in B #a.send(:another_delegated_method).
Could it be that the point with delegates in Ruby is where the delegated method is defined? Meaning that we send from within class A to property #b (#b(:delegated_method)) a :delegated_method defined within A itself?
Hope this isn't too confusing. I myself am confused about why delegates even exist in a duck typing language and what the differences are between Delegator, SimpleDelegator and ActiveSupport's Delegate.

It isn't clear to me that you have understood how delegation works in Cocoa. It is true that the common variety of the delegation pattern in Cocoa involves a protocol, but that's just a way of quieting the compiler.
So let's talk first about quieting the compiler. You can't send the woohoo message to an object in Objective-C unless one of two things is true:
The compiler has reason to believe that this object might respond to the woohoo message.
The compiler is made to suspend judgment.
Nowadays, the first approach is usually used - that's what a protocol is for. But this was not always the case. It used to be that delegation depended mostly on informal protocols. And there still are informal protocols in Cocoa. The idea is that either the method is injected into NSObject by a category, or else you are careful to type the object as id so that it can be sent any message at all.
Now let's talk about dynamism. The reason informal protocols are no longer used is that a feature was introduced allowing protocols to declare optional members. But dynamism is still needed! We may satisfy the compiler, one way or another, but at runtime we have to make sure that it is safe to send a certain message to a certain object. Your app delegate may adopt UIApplicationDelegate, but Cocoa is not going to send it the applicationDidBecomeActive: message unless your app delegate class implements applicationDidBecomeActive: - if it did, you'd crash, and that wouldn't be very nice.
Moreover, if you can just get past the compiler, you can perform delegation in Objective-C even more dynamically than that, as explained here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html
The idea is that we go right ahead at runtime and send the object the message anyway! If a message arrives that Object A can't handle, it can see if Object B handles it. If it does, it passes the message along to Object B. So we might not crash after all!! I use that approach in one of my apps:
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([self.originalDataSource respondsToSelector: aSelector])
return self.originalDataSource;
return [super forwardingTargetForSelector:aSelector];
}
In that code, I'm saying that if a message arrives and I can't handle it, I should try to get it sent on to another object, called self.originalDataSource.
If you think about it, that is almost identical to Ruby delegation. I have a helper object, and messages that I can't handle are passed on to it.
Another common use of this pattern is when wrapping a Cocoa collection. You can't subclass, say, NSArray, because it's a class cluster, so the proper approach is to wrap it. You then just forward everything to the NSArray, and presto, you are duck-typed as an NSArray! You look like an NSArray as far as your methods are concerned. Then you introduce some difference in behavior, and now you are duck-typed as a customized NSArray.

Related

Delegation in Pharo Smalltalk

What is the best way of doing delegation in Smalltalk, more specifically in Pharo? I know of the doesNotUnderstand strategy, but it does not delegates subclassResponsability messages.
I was thinking on something that delegates every message send not explicitly implemented on the class to some specified object, like I can do, for example, with #Delegate in Groovy. Is there some already known way of doing this?
doesNotUndersand: will only work on methods that the object does not understand (thus the name), so if you already have implemented a method it will not be used (as is the case with subclassResponsibility.
If you use Pharo 5 (which should be released this week (May 2016)), you could use MetaLinks. It's a bit of an overkill, however what you are doing doesn't seem right to begin with (why would you want to delegate subclassResponsibility)?
In either case, MetaLinks allow to attach runtime behavior to your methods, for example:
You have some method that you want to delegate
MyObject>>someMethod
^ self subclassResponsiblity
And an object to which you wish to delegate to…
MyObject>>delegate
^ delegate
So you create a MetaLink
link := MetaLink new
metaObject: [ :object :selector :arguments |
object delegate perform: selector withArguments: argument ];
selector: #perform:withArguments:;
arguments: #(object selector arguments);
control: #instead.
Which you can install to any method AST you want.
(MyObject>>someMethod ast) link: link.
Now every time the method will be called, instead (that's what the control: does) of executing the method, the arguments of the message (if any) will be given to the block in metaObject:.
Although this should work and is extremely powerful mechanism, right now there are serious disadvantages that currently being addressed:
no documentation
little tooling support (it's pretty hard to debug)
a lot of work (we are working on a framework that would ease this as you would want to easily install them and uninstall them everywhere you need, but it's not ready yet, so it has to be done by hand)
recompilation removes the link (see point above)
Summary
To summarize, this is possible to do with MetaLinks as I've shown, however at the moment it's quite a lot of work, but we are addressing those issues.
what Peter was talking about is, you can override the
subclassResponsibility, just like you did for the doesNotUnderstand method.
There is no need to override every senders of "self subclassResponsibility".
For example, just delegate to the implementation of doesNotUnderstand
subclassResponsibility
^ self
doesNotUnderstand: (Message selector: thisContext sender selector
arguments: thisContext sender arguments)

What is the purpose of protocols if all methods are optional?

I understand what purpose protocols serve (to have a type conform to a set list of methods or/and properties), but I don't understand what the purpose is of a protocol with all optional methods. One example would be UITextFieldDelegate.
If all methods are optional in a protocol, why would you conform to the protocol instead of just writing the methods from scratch in your class? I don't see what the benefit or purpose of conforming to the protocol is in this case.
Are the optional methods there just as suggestions of functionality that could be implemented?
Historically, for delegates and data sources in Cocoa, informal protocols were used. Informal protocol was implemented trough a category for NSObject class:
#interface NSObject (NSTableViewDelegate)
- (int)numberOfRowsInTableView:(NSTableView *)tableView;
// ...
#end
Later, optional methods in protocols were introduced. This change leads to better documenting of class responsibilities. If you see in code, that class conforms to NSTableViewDelegate, you suspect that somewhere exists a table view, that managed by instance of this class.
Also, this change leads to stronger checks in compile time. If programmer accidentally assign wrong object to delegate or dataSource properties, compiler will warn.
But your assumption is also correct. Optional methods are also suggestions for possible functionality.
By default, all methods in a protocol are required. Each method has to be marks as optional if the nor required for everything to function correctly.
If all methods are optional in a protocol, why would you conform to the protocol instead of just writing the functions from scratch in your class?
Conforming to a protocol allow your class to tell another object the methods it has without the other object needing to know about your class. This is really useful when using Delegation as it allows the delegate to decide what information they wish to receive/provide to another class.
For example,the UIScrollViewDelegate protocol only defines optional methods. Lets say we have a class Foo that we want to know when things change with a UIScrollView.
If we decided to throw that protocol away and implement the functions from scratch, how would we tell UIScrollView which methods we implement and which methods to call when certain event occur? There is no good way it could find out. When UIScrollView was built, it didn't know about Foo so it can't know what methods it implements. Also, Foo has no way of knowing what methods can be called on it by the UIScrollView.
However, when UIScrollView was built, it did know about UIScrollViewDelegate. So if Foo conforms the the UIScrollViewDelegate protocol, there is now a common definition that both Foo and UIScrollView can follow. So Foo can implement any methods it cares about, like scrollViewDidScroll: and the UIScrollView just needs to check if the delegate implemented the methods in UIScrollViewDelegate.
The protocol establishes a contract for the interface between one object and another. The fact that the methods are optional simply says that you don't have to implement that particular method, but you can if your app calls for it.
Generally, if you're conforming to a protocol for which all of the methods are optional, though, you're doing that for a reason, namely that you plan on implementing one or more of those methods. Just because all of the protocol's methods are optional doesn't mean you will not implement any of them, but rather simply that you can elect which are relevant in your particular situation.
For example, consider the UITextFieldDelegate protocol. You'd generally conform to that because you want to specify, for example, whether certain characters should be allowed to be inserted into the text field or what to do when the return key is pressed. Sometimes you only want to implement the former. Sometimes you only want to implement the latter. Sometimes you do both. But just because you choose to implement one or the other doesn't mean you necessarily want to do other one (but you can if you want). Frankly, though, if you really didn't want to implement any of the methods, you probably wouldn't even bother to specify the delegate of the text field, nor bother to specify that you're conforming to the protocol.
Bottom line, the protocol that consists solely of optional methods basically says "if you need it, this is the documented interface for the methods you may elect to implement". The protocol still is very useful to establish the possible interfaces, but doesn't force you to implement those methods you do not need.

Swift: Do protocols even have a real purpose?

I'm wondering why protocols are used in swift. In every case I've had to use one so far (UICollectionViewDelegate, UICollectionViewDataSource) I've noted that they don't even have to be added to the class declaration for my code to work. All they do is make it such that your class needs to have certain methods in it so that it can compile. Beats me why this is useful other then as a little post it note to help you keep track of what your classes do.
I'm assuming I'm wrong though. Would anyone care to point out why to me please?
A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol doesn’t actually provide an implementation for any of these requirements—it only describes what an implementation will look like.
So it's basically an interface, right?
You use an interface when you want to define a "contract" for your code. In most cases, the purpose of this is to enable multiple implementations of that contract. For example, you can provide a real implementation, and a fake one for testing.
Further Reading
Protocols
What is the point of an Interface?
It allows flexible linkage between parts of code. Once the protocol is defined it can be used by code that doesn't need to know what will be done when the methods are called or exactly what object (or struct or enum) is actually being used. An alternative approach could be setting callbacks or blocks but by using a protocol as complete set of behaviours can be grouped and documented.
Some other code will typically create the concrete instance and pass it to the code expecting the protocol (sometimes the concrete instance will pass itself). In some cases neither the implementation of the code using it need to be aware of each other and it can all be set up by some other code to keep it reusable and testable.
It might be possible to do this in some languages by duck typing which is to say that a runtime inspection could allow a object to act in such a context without particular declaration but this is probably not possible to do at compile time in all cases and it could also be error prone if worked out implicitly.

Why does Cocoa binding use both KVC and KVO and not just KVC?

As a newbie to Cocoa and Objective-C I have a rudimentary understanding of KVC and KVO. However with respect to Cocoa Bindings (as covered in the Apple document titled "Cocoa Bindings Programming Topics" see figures 8-10) I'm unclear why they are depicting using both KVC and KVO, when it seems that KVO would be sufficient. KVO's ObserveValueForKeyPath:ofObject:change:context can provide the old and new values so why is KVC mechanisms needed? Note, I see how KVO decouples objects, but so does KVC.
The example Apple gives (figures 8-10) depicts a Window containing a slider and a text input control to visually represent and allow user interaction for setting&viewing "temperature", a Controller object, and a Model Object with a temperature property. So put another way my question is why not just have a bi-directional KVO relationships between the 2 controls and the controller (each registers with the other as an observer), and bi-directional KVO relationships between the Model Object and the Controller? Why is KVC needed?
The long-winded docs are confusing you.
All this does is about code-reusability.
(1) Provide a standard way to declare and manage properties.
(you can do it manually the old way with ivars and setters and getters, but property synthesis gives it to you for free)
You cannot Observe the Key Value Pairs reliably unless they follow a convention.
The convention is KVC. Following that is being KVC compliant.
(2) Provide a highly reusable and generic way for objects to receive notifications about changes to a property in another object. This is KVO.
KVO is the ability to generically code notifications based on changes in properties that are KVC compliant first.
(3) Bindings & Core Data. Both technologies are built on KVC and KVO to make this all work in as generic a way as possible.
It is also quite similar conceptually to ORMs like Active Record and Ruby on Rails.
The magic starts with KVC.
KVC enables a simple KVO mechanism.
KVO + KVC make Bindings and Core Data possible and easy.
They also provide a lot of syntactic sugar and wacky conveniences.
You can treat the interface to KVC compliant objects as a dictionary or an array.
Then all the patterns fall into place.
You can still have other bi-drectional observer patterns.
Delegation (setting eachother as or sharing a delegate) and Notification (via NSNotification), or even simply messaging other objects (likely bad tight coupling if this is your pattern everywhere, leading to these other patterns being created)
These are not wrong, but have some trade-offs.
Notifications can be spaghetti code at times. Like all callbacks, you end up with something like goto sometimes. However, it isn't necessarily as tightly coupled to a specific property of a specific object like KVO. It is just waiting for a potentially very general notification that could contain a lot of different things. However, by its nature, Notifications tend to be more use-case specific, and easy to apply to custom scenarios.
KVO as-a-specific-technology is built on KVC conventions, and does not work without them.
It makes some very basic, common boiler-plate code & tight coupling easier to create.
A few have tried in the comments, he's my go:
KVO is essentially built on top of KVC - when a KVC compliant property is changed if there is an observer then the KVO machinery kicks in, constructs the info dictionary as needed, and sends the message to the observer(s).
If they question is why was it done this way and why not another then that is a different question. KVO needs to plug into something - you can't just observe changes to a variable (memory location) in a simple way[*]. A property, having a setter & getter, is a place things such as KVO can hook in. And properties follow the KVC pattern and there is already machinery to support that... But that doesn't mean KVO has to depend on KVC, other implementations strategies are undoubtedly possible.
HTH at little.
[*] entering the debugging mode and deploying watchpoints is not "simple" in this context!

Using NSProxy and forwardInvocation:

I would like to code a proxy that forwards method invocations to another object over TCP without NSConnection and NSDistanceObject stuff. What I want is my own protocol.
The problem is that subclassing NSProxy and overriding forwardInvocation: is not sufficient. I have also to override methodSignatureForSelector
Here is my question:
– (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return ???
}
#Brian, This may be ok, but setProtocolForProxy: is just for optimization. cocoafan could mandate it for his solution, but it wouldn't be a drop-in replacement. You're supposed to be able to get signatures automatically. To do that, the network protocol needs a way to request the signature.
I believe the solution here is to include in the network protocol a "request method signature" method, and have it run methodSignatureForSelector: on the distant object and encode and return the result. That's what NSDistantObject does.
Providing setProtocolForProxy: is an important optimization if you're going to chatter a lot, but it does restrict you to objects that you have a protocol for, and prior to 10.5 that introduces some annoying limitations (all methods are required). Even on 10.5, it may introduce some problematic limitations if it's the only way to get method signatures.
#cocoafan, I think you're probably right to create this from scratch on top of NSProxy, but do take a look at NSConnection and see if you can sub-class it to manage the network connection the way you want. If you can find a way to do that (though I don't see an easy way right off), you'll probably get a lot of stuff for free from NSDistantObject.
The way NSDistantObject handles this is by its setProtocolForProxy: method, which specifies a protocol containing the list of methods that the object on the other end of the connection handles. It can then use the information for these methods to provide appropriate NSMethodSignature objects when doing forwarding.
It looks like the most straightforward to do that is via the protocol_getMethodDescription() function, declared in <objc/runtime.h>. This returns an objc_method_description struct which contains a types field. I believe you should be able to pass that value into +[NSMethodSignature signatureWithObjCTypes:] to get a method signature object that matches what's declared in the protocol.
I found a smart solution to generate NSInvocation objects.

Resources