Mailing List webobjects-dev@wocommunity.org Message #242
From: Markus Ruggiero (rucotec) <webobjects-dev@wocommunity.org>
Subject: Re: [WO-DEV] ERXGenericRecord takeValueForKey
Date: Sat, 28 Aug 2021 17:02:55 +0200
To: WebObjects & WOnder Development <webobjects-dev@wocommunity.org>
Signed Data (Text SHA256)
Hi OC,

I will try to answer your question from a conceptual angle...

On 26 Aug 2021, at 03:50, ocs@ocs.cz <webobjects-dev@wocommunity.org> wrote:

Hi there,

I must be missing something darn obvious; looks like I've missed EOF 101 somehow :/


Nothing to do with EOF. Well, not directly. See below...

My EO class, which extends ERXGenericRecord, does not implement modelled property setters. Thus, I assumed takeValueForKey would always fall through handleTakeValueForUnboundKey. Seems not.

I've overridden the methods like this:

===
class OCSEnterpriseObject extends ERXGenericRecord {
 static boolean canAccessFieldsDirectly { NO }
 void takeValueForKey(value,String key) {
   println "???takeValueForKey $key"
   //super.takeValueForKey(value, key) // precisely same behaviour as with the thing below, no difference
   NSKeyValueCoding.DefaultImplementation.takeValueForKey(this,value,key)
 }
 void handleTakeValueForUnboundKey(value,String key) {
   println "???handleTakeValueForUnboundKey $key"
   // ... some stuff to simulate setter (eventually using takeStoredValueForKey), not relevant, for it is never called
 }
 ...
}
===

It does NOT work as (I've naïvely) presumed.


Your presumption is wrong.

When eo.takeValueForKey(o,key) is called, I can always see “???takeValueForKey” (naturally), but I *never ever* see “???handleTakeValueForUnboundKey“ for any key amongst modelled attributes. Nothing other (known to me) gets called — not even takeStoredValueForKey, which I've also overridden to log —, but the value is set all right in the EO.

Only if foo is a random (non-existing, non-modelled) string, I can see “???handleTakeValueForUnboundKey“.

Looks like there's some trick in NSKeyValueCoding.DefaultImplementation.takeValueForKey which recognises modelled attributes in EOGenericRecord and fill their values directly, without falling to handleTakeValueForUnboundKey?!? Weird.


No, not weird, not at all.

Or I must be doing something very far wrong.


Ditto no.

Your (and most other folks’s) thinking of key value coding is wrong and way too technical. What actually happens is the following:

Conceptually in object oriented programming objects communicate with each other. This is a 2-fold process. One object sends a message to another object and the receiving object then acts on that message. This distinction is beautifully visible in Objective-C where there are two syntaxes available. One, the classic C call, relies on early binding. This is just a simple function call and the called code is determined at compile time. The other syntax, the one most programmers don’t like (because they don’t understand it), is the [myObj myMessage] thing with the square brackets. This is really message passing in the true sense of the OO paradigm. In this sense you can send any message to any object, even to a non-existing object, and you either get a reaction or you don’t because the receiving object understands your message or is does not. Did you ever wonder why in the WO docs the word “receiver” occurs so often?

Key value coding in WO is a technical implementation of this mechanism. In “modern” languages like Java one cannot send an arbitrary message to any object - there is simply no syntax for it. KVC is the underlying technical implementation to provide exactly this. (Side note: only when Java got introspection in V1.2 or was it 1.4? it became possible to port WO to Java).

Let’s say your EO has a “name” attribute which you define in the EOModel. Any EO can be messaged and if it “understands” the message it will act. If an object sends the “name” message to an EO it will get the contents of the name attribute back if the receiving EO understands this message. It does when it has a “name” attribute, it does not otherwise. The same is true if an object sends the “setName” message.

KVC implements different strategies to make this message passing possible. It looks for direct access possibilities to attributes, it looks for accessor methods and it plays with names for such attributes and methods (name, _name, name(), getName(), etc). It tries hard to overcome the limitations of the programming language to allow the freedom of sending arbitrary messages to any object.

This is also nicely visible for bindings in the wod or when specifying key paths in code. In Java myObject.purchase().car().brand() will crash with a NullPointerException when your purchase does not include a car because you cannot call the brand-method on a null car object. The same in KVC and bindings works: value = myObject.purchase.car.brand; Again current programming languages do not support something like this and depending on your code having accessor methods you might get NPEs nevertheless because you make it so hard for KVC.

Man do I love this stuff! It’s the purest implementation of OO concepts I know of (other than probably Smalltalk). This is the main reason why I use WO when teaching OO programming. I would have used Smalltalk but it had to be a bit more modern language (heh heh heh - the school said so).

---markus---

Is this documented somewhere? Far as I can say, neither ERXGenericRecord nor EOGenericRecord nor NSKeyValueCoding.DefaultImplementation mentions anything special; NSKeyValueCoding.DefaultImplementation.takeValueForKey should simply check for the accessor (either with or without the _ prefix) and if there is none (which there indeed is not), fall to handleTakeValueForUnboundKey. What am I missing here?

Thanks,
OC



#############################################################
This message is sent to you because you are subscribed to
 the mailing list <webobjects-dev@wocommunity.org>.
To unsubscribe, E-mail to: <webobjects-dev-off@wocommunity.org>
To switch to the DIGEST mode, E-mail to <webobjects-dev-digest@wocommunity.org>
To switch to the INDEX mode, E-mail to <webobjects-dev-index@wocommunity.org>
Send administrative queries to  <webobjects-dev-request@wocommunity.org>



Markus Ruggiero


rucotec GmbH                        web https://rucotec.ch
Steinenvorstadt 79                email markus.ruggiero@rucotec.ch
4051 Basel / Switzerland         mobile +41 79 508 4701








Content Unaltered as verified By:
<markus.ruggiero@rucotec.ch>
Subscribe (FEED) Subscribe (DIGEST) Subscribe (INDEX) Unsubscribe Mail to Listmaster