View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000732 | LDMud | LPC Language | public | 2010-03-04 14:37 | 2020-04-28 22:14 |
Reporter | _xtian_ | Assigned To | Gnomi | ||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | resolved | Resolution | fixed | ||
Summary | 0000732: strict resolved call-others? and a new operator | ||||
Description | I don't know if this has ever been proposed. Probably. I have been thinking about an efun that does what call_resolved() does, but with the call_other syntax and throws an error when a call could not be resolved. In brief: call_strict( ob, "fun" ); or a more beautiful ob=>fun() or ob.fun() or ob==>fun() (suggestions) throws an error at runtime, if ob has no accessible function "fun". The reason behind this: In LPC we have no good way to express interface relationships since all our objects are of the same type and call-others at runtime don't need to be resolved. The above is a short-hand for using call_resolved() and checking for an error, but I find it much more expressive and readable and worth being implemented in the language. | ||||
Tags | No tags attached. | ||||
External Data (URL) | |||||
|
I don't really like => or ==> because they are too easily confused with comparisons. The dot would be better, but it may clash with the struct lookup, I don't know if the compiler is clever enough (AFAIR there was once the plan to use -> for struct lookup, which did not work for compiler reasons). |
|
Hmm, the dot also suggests some kind of static checking, which wouldn't be the case here ... |
|
I don't see why the dot suggests static checking more or less than the call_other() operator (->). Why don't we couple strict function resolving to an (existing) pragma? Since load_object() has been added, the number of unresolved function calls should have been decreased significantly. ;-) Besides: Why has call_resolved() been designed to return a success value instead of raising an error, too? One could use function_exists() if he wanted to handle non-existent functions. |
|
Couldn't you achieve this through a simul_efun to call_other ? |
|
We implemented a Warning system for calls to non-existing functions in EverLIB as follows: in our master in inaugurate_master(): set_driver_hook(H_DEFAULT_METHOD, "unresolved_method_call"); in our base object that is inherited by ALL other objects. Parts are EverLIB specific, but I think you get the idea. This works GREAT and it helped us to find ALOT of bugs. Its fast enough too! public status unresolved_method_call(mixed result, string fun, varargs args) { if (object_name(this_object()) + ".c" == __FILE__) { return FALSE; } if (member(omitted_methods, fun) || fun == "reset" || fun == "clean_up" || (sizeof(fun) > 0 && fun[0] == '-')) { return FALSE; } string msg; if (previous_object() == NULL) { msg = sprintf("Non-existing method <%O>::%s() called\n", this_object(), fun); } else { msg = sprintf("<%O> called non-existing method <%O>::%s()\n" , previous_object(), this_object(), fun); } if ( this_player() != NULL && interactive(this_player()) && (status) this_player()->instance_of("/class/interactive/interactive") && ( (status) SECURITY->user_id_exists( (string)this_player()->get_normalized_name() ) || 1 == (int)SE_ACCESS_CONTROL->is_valid_testplayer( this_player() ) ) ) { // send this to the player, but bypass the processing of it send_message(({ MCC_WARNING, M_PL_ONLY, "WARNING: ", msg })); } else { catch(SE_CHANNEL->send("Wrongness", master(), CHANNEL_CMD_SAY, ({ msg }), NULL)); } debug_message(msg, DMSG_STAMP | DMSG_STDOUT | DMSG_STDERR | DMSG_LOGFILE); return FALSE; } So actually, we do not need to distinguish, we already have the functionality ;-) |
|
Thanks for the code snippets, but the original intention is not to change the behaviour of call_other but to offer a second way of external function calling ... albeit a stricter one. In our environment the fact that a not-resolved-call-other results in a legal 0 is used quite a lot and I wouldn't want to change that default. (example: if (ob->query_weapon) // react to a weapon ...) The stricter call would allow code like this: if (ob->query_weapon) ob==>wield(); // if this weapon has not defined a wield() function // this throws an error/warning. this shouldn't happen Of course we could add a custom simul-efun that does this, but I prefer putting this in the open. Also that way we can use a nice operator for it, if we can find a suitable one. |
|
Another possibility would be to change the behaviour of call_other based on a pragma in the caller (or callee?)... But that would of course have a greater impact and your last example would require a different approach to detect the weapon (function_exists, symbol_function, ...). |
|
Implemented in 3.6.2 |
Date Modified | Username | Field | Change |
---|---|---|---|
2010-03-04 14:37 | _xtian_ | New Issue | |
2010-03-04 14:44 | zesstra | Note Added: 0001760 | |
2010-03-04 14:56 | _xtian_ | Note Added: 0001761 | |
2010-03-04 16:57 | Largo | Note Added: 0001762 | |
2010-03-05 10:56 | bubbs | Note Added: 0001763 | |
2010-03-05 13:08 | Bardioc | Note Added: 0001764 | |
2010-03-10 16:41 | _xtian_ | Note Added: 0001780 | |
2010-03-14 10:17 | zesstra | Note Added: 0001795 | |
2020-04-28 22:13 | Gnomi | Assigned To | => Gnomi |
2020-04-28 22:13 | Gnomi | Status | new => assigned |
2020-04-28 22:14 | Gnomi | Status | assigned => resolved |
2020-04-28 22:14 | Gnomi | Resolution | open => fixed |
2020-04-28 22:14 | Gnomi | Note Added: 0002529 |