X-CGP-ClamAV-Result: CLEAN X-VirusScanner: Niversoft's CGPClamav Helper v1.22.2a (ClamAV engine v0.102.2) X-Junk-Score: 0 [] X-KAS-Score: 0 [] From: "ocs@ocs.cz" Received: from smtp-beta-1.zoner.com ([217.198.120.8] verified) by post.selbstdenker.com (CommuniGate Pro SMTP 6.3.3) with ESMTPS id 26366993 for webobjects-dev@wocommunity.org; Sat, 28 Aug 2021 20:38:57 +0200 Received-SPF: none receiver=post.selbstdenker.com; client-ip=217.198.120.8; envelope-from=ocs@ocs.cz Received: from smtp.zoner.com (smtp.zoner.com [217.198.120.6]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp-beta-1.zoner.com (Postfix) with ESMTPS id C65B5180016A for ; Sat, 28 Aug 2021 20:38:37 +0200 (CEST) Received: from smtpclient.apple (smtp2stechovice.cli-eurosignal.cz [77.240.99.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: ocs@ocs.cz) by smtp.zoner.com (Postfix) with ESMTPSA id 597D03000075 for ; Sat, 28 Aug 2021 20:38:37 +0200 (CEST) Content-Type: multipart/alternative; boundary="Apple-Mail=_B836C90E-89E5-42BA-BEEA-30410934B9B4" Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.80.0.2.43\)) Subject: Re: [WO-DEV] ERXGenericRecord takeValueForKey Date: Sat, 28 Aug 2021 20:38:36 +0200 References: To: WebObjects & WOnder Development In-Reply-To: Message-Id: <639FDC2F-3D15-4328-8932-E649829A81B9@ocs.cz> X-Mailer: Apple Mail (2.3654.80.0.2.43) --Apple-Mail=_B836C90E-89E5-42BA-BEEA-30410934B9B4 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Markus, well thanks for an answer, but I'm afraid it's mostly quite beside the = point. Anyway, the one single thing which seems relevant to my question = is > Let=E2=80=99s say your EO has a =E2=80=9Cname=E2=80=9D attribute which = you define in the EOModel. Any EO can be messaged and if it = =E2=80=9Cunderstands=E2=80=9D the message it will act. If an object = sends the =E2=80=9Cname=E2=80=9D 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 =E2=80=9Cname=E2=80=9D attribute, it does = not otherwise. The same is true if an object sends the =E2=80=9CsetName=E2= =80=9D message. where the =E2=80=9C... if the receiving EO understands this message. It = does when it has a =E2=80=9Cname=E2=80=9D attribute, it does not = otherwise ...=E2=80=9D of yours is essentially what I meant by >> Looks like there's some trick in = NSKeyValueCoding.DefaultImplementation.takeValueForKey which recognises = modelled attributes in EOGenericRecord but alas it does not answer the subsequent questions: >> 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? Let me please to re-phrase the problem quoting more of the documentation = than originally (for I've originally thought it should not be = necessary). (i) NSKeyValueCoding.DefaultImplementation.takeValueForKey is documented = very explicitly to - try a plain setter (e.g., setName for a key =E2=80=9Cname=E2=80=9D) - if it fails, to try an underscored setter (e.g., _setName) - if it fails, to try some fields (e.g., name, isName and more), too, = unless canAccessFieldsDirectly is false. In my case it is false (and = besides there are no such fields anyway, I've actually checked) - if none of the above steps helps, to invoke = handleTakeValueForUnboundKey (if implemented, which, in my case, it is). Note that there is no mention of enterprise objects, models etc.; that = makes a perfect sense, for this is the Foundation level which does not = (at least, should not) know anything of them; EOF is implemented above = Foundation and the lower tiers do not (at least, should not) know = anything of the upper ones, (ii) therefore, given the implementation marked [1] below, I would = assume, when takeValueForKey(value,'name') is called, the following = happens: - my overridden method gets called and prints out =E2=80=9C???takeValueFor= Key name=E2=80=9D. Check, that happens all right; - since there is neither a setName nor _setName method[2], now I would = assume my handleTakeValueForUnboundKey method gets called and and prints = out =E2=80=9C???handleTakeValueForUnboundKey name=E2=80=9D Oops. The latter never happens if =E2=80=9Cname=E2=80=9D is a modelled = attribute (which makes it self-evident the problem is EOF-level). It = happens all right for other keys (for which there's no setter method). My question is: how on earth is is possible that = NSKeyValueCoding.DefaultImplementation.takeValueForKey of Foundation, = called over an ERXGenericRecord, can recognise a modelled attribute, and = instead of invoking handleTakeValueForUnboundKey as documented sets that = attribute's value? What the H. happens in there (and where is it = documented)? I could quite understand if EOGenericRecord.takeValueForKey was = overridden to recognise and set the modelled attributes; that would make = a perfect sense. Nevertheless (a) this is nowhere documented far as I = was able to find, and (b) even if it was, it should apply only if I = called =E2=80=9Csuper.takeValueForKey=E2=80=9D at [3], but never with = the actual =E2=80=9CNSKeyValueCoding.DefaultImplementation.takeValueForKey= =E2=80=9D code. Far as I can say, Wonder does not override = NSKeyValueCoding.DefaultImplementation, (like it does with other = Foundation classes, notably the containers, e.g., NSArray) so that's not = an answer either. (And to make it even worse, not even takeStoredValueForKey gets called = in the process. What the?!?) That's my problem and that's the question I am seeking an answer for. [2] I've checked (to be extra sure, I've checked also for the fields, = regardless canAccessFieldsDirectly). The setters indeed do not exist = (they hardly could, unless ERXGenericRecord or EOGenericRecord created = them runtime through some very arcane Java magic; I think it is not = possible, but I might be wrong. In ObjC there is an API to do such = things, but Java =E2=80=93 very unfortunately =E2=80=93 does not support = this, far as I know). That aside, the rest is rather a completely different debate which, I am = afraid, does not belong to this particular mail thread (although in = different contexts could be very interesting and, at the very least for = most people with a Java background, also rather at the enlightening = side. I am adding a couple of comments just for possible benefit of = those, if anyone such happens to read on =E2=80=94 which I somewhat = doubt, but who knows :)) > On 28. 8. 2021, at 17:02, Markus Ruggiero (rucotec) = wrote: >> On 26 Aug 2021, at 03:50, ocs@ocs.cz = > = wrote: > Your (and most other folks=E2=80=99s) thinking of key value coding is = wrong and way too technical. Um, =E2=80=9Cway too technical=E2=80=9D is precisely what happens when a = computer runs a compiled code. It's often expressed as the old adage = =E2=80=9CBloody thing does what I told it to; not what I wanted to.=E2=80=9D= > 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. Which applies perfectly with ObjC or Smalltalk or Ruby or any other = object-oriented language; Java though is an ugly half-OO mess in which = it is not that easy. In pure Java you do not and cannot =E2=80=9Csend a message=E2=80=9D; the = thing allows you just to =E2=80=9Ccall a method=E2=80=9C (at best found = through the reflexion =E2=80=94 which nevertheless is considerably = slower than real message-sending =E2=80=94, at worst hard-compiled, = which is about of same speed, but terribly inflexible). It's = considerably closer to the C++ disaster than to a real OO language. > 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=E2=80=99t like (because they don=E2=80=99t 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=E2=80=99t because the receiving object = understands your message or is does not. Indeed. Completely irrelevant for our case though. (And in ObjC somewhat = misleading, for in there are other syntaxes available as well, e.g., you = can call objcSend directly, which boils down to same result as [foo = bar]; you can cache the IMP and call it manually, and more.) Java is, alas, much more limited. Its (instance-level) method-calling = works in a roughly similar way ObjC message-sending does, and mostly =E2=80= =94 mostly! =E2=80=94 something like Java's = =E2=80=9CanArray.arrayByAddingObject(foo)=E2=80=9D and ObjC =E2=80=9C[anAr= ray arrayByAddingObject:foo]=E2=80=9D are functionally equivalent. Not = always though; in ObjC anArray can be a proxy which processes any = message received in a special way (e.g., sending it over an IPC to = another process). In Java, this is very difficult =E2=80=94 actually = impossible in full extent =E2=80=94, leading to an incredible amount of = ugly boilerplate code. (About the closest to proxying we can find in = Java is EOFaulting =E2=80=94 compare it with the ObjC implementation of = faults!) > Key value coding in WO is a technical implementation of this = mechanism. Not at all. KVC is a mechanism which allows one to access object properties by name. = It originated in the very ObjC (unless it's older and Smalltalk-based; = Ito be frank, I can't recall =E2=80=94 I did not use Smalltalk in ages. = Anyway, it is well possible), and has been very handy in there, = regardless ObjC, being a real OO language, offers full-fledged proper = message-sending naturally. KVC can be (and was) implemented in there, as ObjC does with its =E2=80=9C= [foo valueForKey:bar]=E2=80=9D. It can be implemented just as well over = (much less flexible and much less convenient) method-calling, as Java = does with its =E2=80=9Cfoo.valueForKey(bar)=E2=80=9D. In both cases, the = implementation is conceptually similar (aside of the Java-induced = boilerplate, but that's again beside the point). > In =E2=80=9Cmodern=E2=80=9D languages like Java one cannot send an = arbitrary message to any object - there is simply no syntax for it. Indeed, which makes Java a terribly inferior language :( It's real bad = Apple thrown out ObjC-based WO+EOF. (Incidentally there are modern = languages which do support proper message sending =E2=80=94 albeit often = hidden under a very misleading and ugly API which looks like = method-calling; an example of these is Ruby.) > KVC is the underlying technical implementation to provide exactly = this. Definitely not. The technical implementation of = something-as-close-to-proper-message-sending-as-possible in Java is the = NSSelector API. > (Side note: only when Java got introspection in V1.2 or was it 1.4? it = became possible to port WO to Java). That's right, but still, even today's Java is terribly deficient; its = introspection and runtime APIs are sorely lacking. As aforementioned, = you can't really implement a full-fledged proxy in Java. Another problem = is that you can't manage methods of an objects; there's nothing like the = ObjC runtime API and it's a big bad one (e.g., you can't add accessors = on-demand, as e.g., CoreData does). The Java static =E2=80=9Cmethods=E2=80= =9D are not methods at all, and the way they are inherited is a bad joke = (it's something like the terrible C++ non-virtual inheritance). There's = more problems (e.g., there's nothing like the +load ObjC method in = Java). Frankly I can't think of worse idea of late than was the turning WO+EOF = to pure Java =E2=80=93 well perhaps but for the one to completely stop = supporting WO+EOF publicly and making it a completely internal = Apple-only stuff :/ > Let=E2=80=99s say your EO has a =E2=80=9Cname=E2=80=9D attribute which = you define in the EOModel. Any EO can be messaged and if it = =E2=80=9Cunderstands=E2=80=9D the message it will act. If an object = sends the =E2=80=9Cname=E2=80=9D message to an EO it will get the = contents of the name attribute back if the receiving EO understands this = message. Regardless all the Java deficiencies mentioned above, at this particular = level, there's no difference at all. Namely, the above can be re-phrased = this way for the Java-crippled API, and the result is just as convenient = for the programmer with precisely same level of flexibility: Let=E2=80=99s say your EO has a =E2=80=9Cname=E2=80=9D attribute which = you define in the EOModel. Any EO's valueForKey message can be called = and if it =E2=80=9Cunderstands=E2=80=9D the method argument it will act. = If an object calls the method with the =E2=80=9Cname=E2=80=9D argument = to an EO it will get the contents of the name attribute back if the = receiving EO understands this key. > It does when it has a =E2=80=9Cname=E2=80=9D attribute, it does not = otherwise. The same is true if an object sends the =E2=80=9CsetName=E2=80=9D= message. Indeed. I am asking =E2=80=9Cwhy directly st the valueForKey level=E2=80=9D= (instead of handleTakeValueForUnboundKey), and =E2=80=9Cwhere is this = documented=E2=80=9D. > 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. Definitely not. What it does (and for a price of heaps of boilerplate = does pretty well) is to try hard to overcome the limitations of the = darned Java thing to allow the freedom of accessing arbitrary properties = of any object (by name). On the other hand, it does nothing at all to support arbitrary messages. = NSSelector does that (far as reasonably possible). > This is also nicely visible for bindings in the wod or when specifying = key paths in code. Not surprisingly, since wo-bindings (incidentally, does anyone really = use wods these days, instead of inline bindings in the html template?) = are simply and straightforwardly implemented by KVC :) > 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 =3D myObject.purchase.car.brand; Indeed, KVC does propagate nulls automatically (as any decent API = should, but triple alas, Java does not). > 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. Some of them can support null-propagation with specific syntax, usually = something like foo?.bar. Some of them can be improved to ensure = automatic null-propagation=E2=80=94 myself, I use Groovy with my own = compiler-plugins which do precisely that :) No NPE-hell anymore :)=20 > Man do I love this stuff! It=E2=80=99s the purest implementation of OO = concepts I know of (other than probably Smalltalk). Smalltalk aside, aforementioned ObjC is worlds better OO than anything = Java-based. Sometimes, it gets a bit complex due to the plain-C support = and plain-C types (they make e.g., message forwarding considerably more = complex than it would be otherwise), but that's about the only drawback = of the thing (well, perhaps along with some irregularities in the = dot-syntax for accessors, and its overall syntax for closures). > 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). Myself, if Smalltalk was forbidden and for any reason I could not use = ObjC either, my first option would be Ruby. If interfacing with Java was = needed e.g., to use existing libraries or so, then Groovy. All the best, OC --Apple-Mail=_B836C90E-89E5-42BA-BEEA-30410934B9B4 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 Markus,

well thanks for an answer, but I'm afraid it's mostly quite = beside the point. Anyway, the one single thing which seems relevant to = my question is

Let=E2=80=99= s say your EO has a =E2=80=9Cname=E2=80=9D attribute which you define in = the EOModel. Any EO can be messaged and if it =E2=80=9Cunderstands=E2=80=9D= the message it will act. If an object sends the =E2=80=9Cname=E2=80=9D = 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 = =E2=80=9Cname=E2=80=9D attribute, it does not otherwise. The same is = true if an object sends the =E2=80=9CsetName=E2=80=9D = message.

where the =E2=80=9C... if the receiving EO understands this = message. It does when it has a =E2=80=9Cname=E2=80=9D attribute, it does = not otherwise ...=E2=80=9D of yours is essentially what I meant = by

Looks like there's some trick in = NSKeyValueCoding.DefaultImplementation.takeValueForKey which recognises = modelled attributes in = EOGenericRecord
but alas it does not answer the = subsequent questions:

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?

Let me please to re-phrase the problem quoting more of the = documentation than originally (for I've originally thought it should not = be necessary).

(i) NSKeyValueCoding.DefaultImplementation.takeValueForKey = ;is documented very explicitly to
- try a plain setter (e.g., = setName for a key =E2=80=9Cname=E2=80=9D)
- = if it fails, to try an underscored setter (e.g., _setName)
- if it fails, to try some fields = (e.g., name, isName and more), too, = unless canAccessFieldsDirectly is false. In my = case it is false (and besides there are no such fields = anyway, I've actually checked)
- if none of the above steps = helps, to invoke handleTakeValueForUnboundKey (if = implemented, which, in my case, it is).

Note that there is no mention of enterprise = objects, models etc.; that makes a perfect sense, for this is the = Foundation level which does not (at least, should not) = know anything of them; EOF is implemented above Foundation and the lower = tiers do not (at least, should not) know anything of = the upper ones,

(ii) therefore, = given the implementation marked [1] below, I would assume, when takeValueForKey(value,'name') is called, the following = happens:
- my overridden method gets called and prints out = =E2=80=9C???takeValueForKey name=E2=80=9D. Check, that happens all = right;
- since there is neither a setName = nor _setName method[2], now I would assume my handleTakeValueForUnboundKey method gets called and and = prints out =E2=80=9C???handleTakeValueForUnboundKey = name=E2=80=9D

Oops. The latter never happens if =E2=80=9Cname=E2=80=9D is a modelled = attribute (which makes it self-evident the problem is = EOF-level). It happens all right for other keys (for which there's no = setter method).

My question is: how on earth is is possible that NSKeyValueCoding.DefaultImplementation.takeValueForKey = ;of Foundation, called over an ERXGenericRecord, = can recognise a modelled attribute, and instead of invoking handleTakeValueForUnboundKey as documented sets that = attribute's value? What the H. happens in there (and where is it = documented)?

I could quite = understand if EOGenericRecord.takeValueForKey was overridden to = recognise and set the modelled attributes; that would make a perfect = sense. Nevertheless (a) this is nowhere documented far as I was able to = find, and (b) even if it was, it should apply only if I called = =E2=80=9Csuper.takeValueForKey=E2=80=9D at [3], but never with the = actual =E2=80=9CNSKeyValueCoding.DefaultImplementation.takeValueForKey=E2=80= =9D code.

Far as I can say, Wonder = does not override NSKeyValueCoding.DefaultImplementation, (like it does = with other Foundation classes, notably the containers, e.g., NSArray) so that's not an answer either.

(And to make it even worse, not even takeStoredValueForKey gets called in the process. What = the?!?)

That's = my problem and that's the question I am seeking an answer for.

[2] I've checked = (to be extra sure, I've checked also for the fields, regardless canAccessFieldsDirectly). The setters indeed do not exist = (they hardly could, unless ERXGenericRecord or EOGenericRecord created them runtime through some = very arcane Java magic; I think it is not possible, but I might be = wrong. In ObjC there is an API to do such things, but Java =E2=80=93 = very unfortunately =E2=80=93 does not support this, far as I = know).

That aside, the = rest is rather a completely different debate which, I am afraid, does = not belong to this particular mail thread (although in different = contexts could be very interesting and, at the very least for most = people with a Java background, also rather at the enlightening side. I = am adding a couple of comments just for possible benefit of those, if = anyone such happens to read on =E2=80=94 which I somewhat doubt, but who = knows :))

On 28. 8. 2021, at 17:02, Markus Ruggiero = (rucotec) <webobjects-dev@wocommunity.org> wrote:
On 26 = Aug 2021, at 03:50, ocs@ocs.cz <webobjects-dev@wocommunity.org> = wrote:
Your (and most other = folks=E2=80=99s) thinking of key value coding is wrong and way too = technical.

Um, =E2=80=9Cway too technical=E2=80=9D is = precisely what happens when a computer runs a compiled code. It's often = expressed as the old adage =E2=80=9CBloody thing does what I told it to; = not what I wanted to.=E2=80=9D

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.

Which applies perfectly with ObjC or Smalltalk or = Ruby or any other object-oriented language; Java though is an ugly = half-OO mess in which it is not that easy.

In pure Java you do not and cannot =E2=80=9Csend a = message=E2=80=9D; the thing allows you just to =E2=80=9Ccall a method=E2=80= =9C (at best found through the reflexion =E2=80=94 which nevertheless is = considerably slower than real message-sending =E2=80=94, at worst = hard-compiled, which is about of same speed, but terribly inflexible). = It's considerably closer to the C++ disaster than to a real OO = language.

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=E2=80=99t = like (because they don=E2=80=99t 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=E2=80=99t because the receiving object = understands your message or is does = not.

Indeed. = Completely irrelevant for our case though. (And in ObjC somewhat = misleading, for in there are other syntaxes available as well, e.g., you = can call objcSend directly, which boils down to same result as [foo = bar]; you can cache the IMP and call it manually, and = more.)

Java is, alas, much more = limited. Its (instance-level) method-calling works in a roughly similar = way ObjC message-sending does, and mostly =E2=80=94 mostly! =E2=80=94 something like Java's = =E2=80=9CanArray.arrayByAddingObject(foo)=E2=80=9D and ObjC =E2=80=9C[anAr= ray arrayByAddingObject:foo]=E2=80=9D are functionally equivalent. Not = always though; in ObjC anArray can be a proxy which processes = any message received in a special way (e.g., sending it over an IPC to = another process). In Java, this is very difficult =E2=80=94 actually = impossible in full extent =E2=80=94, leading to an incredible amount of = ugly boilerplate code. (About the closest to proxying we can find in = Java is EOFaulting =E2=80=94 compare it with the ObjC = implementation of faults!)

Key value coding in WO is a technical = implementation of this mechanism.

Not at all.

KVC = is a mechanism which allows one to access object = properties by name. It originated in the very ObjC (unless it's = older and Smalltalk-based; Ito be frank, I can't recall =E2=80=94 I did = not use Smalltalk in ages. Anyway, it is well possible), and has been = very handy in there, regardless ObjC, being a real OO language, offers = full-fledged proper message-sending naturally.

KVC can be (and was) implemented in there, as ObjC = does with its =E2=80=9C[foo valueForKey:bar]=E2=80=9D. It can be = implemented just as well over (much less flexible and much less = convenient) method-calling, as Java does with its = =E2=80=9Cfoo.valueForKey(bar)=E2=80=9D. In both cases, the = implementation is conceptually similar (aside of the Java-induced = boilerplate, but that's again beside the point).

In =E2=80=9Cmodern=E2=80=9D = languages like Java one cannot send an arbitrary message to any object - = there is simply no syntax for it.

Indeed, which makes Java a terribly inferior = language :( It's real bad Apple thrown out ObjC-based WO+EOF. = (Incidentally there are modern languages which do support proper message = sending =E2=80=94 albeit often hidden under a very misleading and ugly = API which looks like method-calling; an example of these is = Ruby.)

KVC is = the underlying technical implementation to provide exactly = this.

Definitely not. The technical implementation of = something-as-close-to-proper-message-sending-as-possible in Java is the = NSSelector API.

(Side note: only when Java got introspection = in V1.2 or was it 1.4? it became possible to port WO to = Java).

That's= right, but still, even today's Java is terribly deficient; its = introspection and runtime APIs are sorely lacking. As aforementioned, = you can't really implement a full-fledged proxy in Java. Another problem = is that you can't manage methods of an objects; there's nothing like the = ObjC runtime API and it's a big bad one (e.g., you can't add accessors = on-demand, as e.g., CoreData does). The Java static =E2=80=9Cmethods=E2=80= =9D are not methods at all, and the way they are inherited is a bad joke = (it's something like the terrible C++ non-virtual inheritance). There's = more problems (e.g., there's nothing like the +load ObjC method in Java).

Frankly I can't think of worse idea of late than = was the turning WO+EOF to pure Java =E2=80=93 well perhaps but for the = one to completely stop supporting WO+EOF publicly and making it a = completely internal Apple-only stuff :/

Let=E2=80=99s say your EO has a =E2=80=9Cname=E2= =80=9D attribute which you define in the EOModel. Any EO can be messaged = and if it =E2=80=9Cunderstands=E2=80=9D the message it will act. If an = object sends the =E2=80=9Cname=E2=80=9D message to an EO it will get the = contents of the name attribute back if the receiving EO understands this = message.

Regardless all the Java deficiencies mentioned = above, at this particular level, there's no difference at all. Namely, = the above can be re-phrased this way for the Java-crippled API, and the = result is just as convenient for the programmer with precisely same = level of flexibility:

Let=E2=80=99s say your EO has a =E2=80=9Cname=E2=80=9D = attribute which you define in the EOModel. Any EO's valueForKey message can be called and if it =E2=80=9Cunderstands=E2=80= =9D the method = argument it will act. If an object calls the method with the =E2=80=9Cname=E2=80=9D argument to an EO it will get = the contents of the name attribute back if the receiving EO = understands this key.

It does when it has a =E2=80=9Cname=E2=80=9D attribute, it = does not otherwise. The same is true if an object sends the = =E2=80=9CsetName=E2=80=9D = message.

Indeed. I am asking =E2=80=9Cwhy directly st the = valueForKey level=E2=80=9D (instead of handleTakeValueForUnboundKey), and =E2=80=9Cwhere is this = documented=E2=80=9D.

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.

Definitely not. What it does (and for a price of = heaps of boilerplate does pretty well) is to try hard to overcome the = limitations of the darned Java thing to allow the freedom of accessing arbitrary properties of any = object (by name).

On the other hand, = it does nothing at all to support arbitrary messages. NSSelector does that (far as reasonably = possible).

This is = also nicely visible for bindings in the wod or when specifying key paths = in code.

Not = surprisingly, since wo-bindings (incidentally, does anyone really use = wods these days, instead of inline bindings in the html template?) are = simply and straightforwardly implemented by KVC :)

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 =3D = myObject.purchase.car.brand;

Indeed, KVC does propagate nulls automatically (as = any decent API should, but triple alas, Java does not).

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.

Some of them can support null-propagation with = specific syntax, usually something like foo?.bar. Some = of them can be improved to ensure automatic null-propagation=E2=80=94 = myself, I use Groovy with my own compiler-plugins which do precisely = that :) No NPE-hell anymore :) 

Man do I love this stuff! It=E2=80=99s the = purest implementation of OO concepts I know of (other than probably = Smalltalk).

Smalltalk aside, aforementioned ObjC is worlds better OO than anything Java-based. Sometimes, it = gets a bit complex due to the plain-C support and plain-C types (they = make e.g., message forwarding considerably more complex than it would be = otherwise), but that's about the only drawback of the thing (well, = perhaps along with some irregularities in the dot-syntax for accessors, = and its overall syntax for closures).

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).

Myself, = if Smalltalk was forbidden and for any reason I could not use ObjC = either, my first option would be Ruby. If interfacing with Java was = needed e.g., to use existing libraries or so, then Groovy.

All the best,
OC

= --Apple-Mail=_B836C90E-89E5-42BA-BEEA-30410934B9B4--