Previous Entry Share Next Entry
Release 0.6.3 -- Introspection
querki
jducoeur wrote in querki_project
Today's major feature came out of a conversation with mindways about how he would like his code to work. My original reaction had been that he was pushing DWIM beyond the breaking point, but as we went along, I realized that something pretty close to what he wanted was doable. And once I began to implement it, I realized that it was, essentially, the beginnings of Querki's version of Introspection.

Don't read too much into that -- I'm not providing anything like a full Introspection library yet. But I'm content to add bits and pieces as they make sense. This one turns out to make certain kinds of code *much* more concise and clear, so it's a solid win. It consists of a bunch of new functions.

The major new function is _foreachProperty(... code ...). You feed a Thing or a Model Value into it, and it runs the given code over each Property in that value. What makes it neat, though, is that it isn't running the code over the property *values*, but instead over the fully-detailed *representation* of the code. You then use the other functions to get at the bits of that representation you want.

This is probably best understood with a simple example:
[[My Thing -> _foreachProperty(""[[_prop -> Name]]: [[_val]]"") -> _bulleted]]
This displays all of the Properties of My Thing, showing the Name of the Property and its Value.

_foreachProperty() iterates over the Properties in the by-now-usual fashion. If you have defined Instance Properties on the Thing's Model, then it will show exactly those Properties in exactly that order. Otherwise, it will show all of the Properties, in alphabetical order. (You will usually want to define Instance Properties -- all Things contain some system-level Properties that you usually don't care about.)

The supporting functions, which you can use inside of _foreachProperty(), are:
  • _prop produces the Property itself, so you can use the meta-Properties of that Property.

  • _val produces the Value of this Property on this Thing. (Which may be inherited from its Model.)

  • _isInherited produces False iff the Value is defined on this Thing itself, or True iff it is inherited from a Model.

  • _definedOn produces the Thing that this Property is on. In the example above, that will always be My Thing, so it seems pointless in simple cases. But if, say, you feed a *List* of Things to _foreachProperty(), it can be invaluable to keep track of what's what.
I'm pretty sure that this is just the beginning of what will become a substantial library of functions. Feel free to request more Introspection functions as they become useful. It's pretty powerful -- in fact, now that I think about it, it's a major step towards being able to rewrite Querki's Editor UI *in* Querki itself.


Other changes in this release:

Added the Copy Into Instances meta-Property: this one is super-advanced, but useful in certain data-entry situations. If you put Copy Into Instances on a Property, and that Property is defined on your Model, then the Model's value of this Property will be copied directly into new Instances when they are created. Therefore, you can assign the value to the children permanently -- helpful in a few situations where you want the target value to be permanent, but the value for new Instances will evolve over time.


Bugfix: Properties now dereference Lists of Things correctly: I'm appalled that we got this far before detecting this bug, because it is quite fundamental. At issue is what happens when you say something like:
[[My Model._instances -> My Number Prop]]
You would expect this to produce a list of numbers -- the values of My Number Prop on each Instance of My Model. But in fact, it has always been producing only the value of the *first* Instance: property dereferencing was only using the first element of the received collection.

This is now fixed, and *should* work much more consistently. Keep in mind that this is the general motif of Querki programming: each Stage should either do something to the received collection as a whole, or should transform each element in it. If you find a case where that isn't true, it's probably a bug; please bring it to my attention. (Fortunately, now that the number of unit tests is skyrocketing, problems like this should become less common.)
Tags:

?

Log in

No account? Create an account