I've just checked in a fix that makes the resolver code in the master even uglier as well as making it possible to do both -> and [] on dirnodes and joinnodes. Feedback is good.
You lose type checking when you need to use the construct
n[""]["delete_value"](p);
instead of
n->delete_value(p);
Writing resolver code with typechecking is bad enough. Without is to ask for trouble.
It's obviously not the first choice. Other ideas was to make an interface object "Dirnode" that handles the actual user interface (indexing, indices, values, sizeof) and have "dirnode" as internal object. Another to return an "internal" object by some secret handshake (e.g. [""]). Both of these however needs more objects. The first one two per module and the second one would create one for every internal peek into the object.
Hopefully most people spend their time writing other things than resolvers, so the tradeoff "more difficult to write resolver"/"easier writing non-resolvers" feels right to me.
But why do you want to redefine the behaviour of `->() in the first plaxe? I don't see any need at all.
The obvious reason is that in 99.9% of all cases [] and -> do the same thing, i.e, index the object with the given value.
It causes confusing when some modules can only be indexed with [], but most other with both.
So the problem is that some modules accept being indexed with `->()?
In that case I'd say "always was" rather than "is", now that there has to be unknown code out in the wild assuming that a safe thing to use. (It's probably possible to break down "always" into fix version ranges of course, but you get the general idea of the thought.)
I see it as a definite feature that only [] is overloaded in dir- and joinnodes, so that -> is free to access the functions and stuff in the objects themselves. It's not bad to have those two different uses well separated. I'd do it that way too if I were to write some kind of intelligent mapping-lookalike-thingy.
I typically write Protocols.HTTP, which in the innards of the compiler becomes Protocols["HTTP"]. When would anyone use that directly? If the resolving must be dynamic then I'd use master()->resolv("Protocols.HTTP").
When would anyone use that directly?
For dynamic loading, as noted below
If the resolving must be dynamic then I'd use master()->resolv("Protocols.HTTP").
Actually, doing exactly that is what caused the problem. :-)
object HTTP = master()->resolv("Protocols.HTTP"); HTTP->get_url_data;
(3) Result: 0
Protocols.HTTP.get_url_data;
(4) Result: Protocols.HTTP.get_url_data
Yes, but HTTP is clearly typed as an object, and objects are typically indexed with ->.
Typed where? At the semantic level it's clearly a module, i.e. a special kind of object which behave in a particular way.
Well, the obvious solution is to do it the same way all the way down, i.e. master()->resolv("Protocols.HTTP.get_url_data"), but that can of course get kinda clumsy too sometimes.
I think it's much better to clearly state in suitable places that . or [] is the way to index modules.
I think it's much better to clearly state in suitable places that . or [] is the way to index modules.
If it were possible to use '.' on non-constant objects I would not mind this at all.
IE, make '.X' into an alias for '["X"]', and let the optimizer do the constant optimization as far as it's possible.
<subsection title="The indexing operator"> <p> If a <ref>lfun::`[]</ref> is defined in a module it will be called when the module is indexed using the .-operator. </p> </subsection>
That's exactly the reverse, it does not say anything about how you should index a module, only how to overload the '.' operator.
Since '.' is the module indexing operator it means that `[] is used to index modules.
Wherever does it say that '.' is the module indexing operator?
And even if it were, it only says that it's possible to overload the module indexing operator (.) using `[], for some unspecified reason.
Personally I think it's odd that . uses `[] and not `->
It says that there may be modules that expect lfun::`[]() to be called when they are indexed. The only way normal pike code can emulate that behaviour dynamically is by using the `[] operator to index the module.
It says that there may be modules that expect lfun::`[]() to be called when they are indexed. The only way normal pike code can emulate that behaviour dynamically is by using the `[] operator to index the module.
Well, yes, I and perhaps 50 other people in the world know that.
I was referring to the manual not exactly beeing clear-as-glass with regard to this issue.
It's not, as an example, written in the tutorial when it mentions modules.
And yet again, why is it `[] and not `->? `-> feels more natural for this operation (indexing with (usually) constant string, instead of dynamic variable)
pike-devel@lists.lysator.liu.se