Comments on: Modules: how to overwrite system functions?
The question has been asked: how does a program overwrite system functions? For example, if you want to use your own custom send function, how would you do that?
Before the question can be answered, you (the programmer) must decide if:
you only need the new function in your own code, or
you need all system code to use the new function.
The first is easy. You would just overwrite the function word:
send: func [....] [... my new function ...]
This would change the send function for your "current context" - your program (script).
The second question is deeper, because you must know that your change is compatible with the rest of the system. Assuming that it is, there are two mechanisms to make the system-wide change:
Provide the "patch" early in the boot process. The new function must be set before any other modules import the function. REBOL would provide a method for doing this (similar to the REBOL.r file, but with greater security).
Request a system-wide re-set for the new function. This method would overwrite the function variable in all modules (or in specific modules). But, there are issues to consider. For instance, what if a module has made its own changes to the function? Now there is a conflict. One solution is for the re-set function to provide a /force refinement that would reset all instances. When the refinement is not set, only those instances that refer to the original definition would be changed.
Note: More information to be provided during testing stages.
How about a reboot? Would work like 1. With a temporary patch-area. The original script would provide the patches, a "main" and reboot. Then everything would be loaded again. Works as if the patches where installed - for this run.
Better to analyze and reproduce than re-setting things IMHO.
Brian Hawley 6-Sep-2006 14:14:47
For security and stability reasons, I prefer to require that a module that redefines the system word would need to be included by your module for the redefinition to take. In my code I find myself trying to screen for redefined system words, rather than encouraging their redefinition.
If you are not going to require the redefinitions to be explicitly requested, at least throw up a security requester or something.
Does this apply to words that are exported read-and-run-only? If not, then that would be a sufficient restriction for me.
Maxim Olivier-Adlhoch 7-Sep-2006 22:44:06
volker, if rebol where scoped, it would work, but because every word, is bound statically within blocks as they are evaluated, once your code is run, you cannot assume a function exists the same it did when it was first loaded. its name might have changed due to program logic *and/or* be redefined.
Maxim Olivier-Adlhoch 7-Sep-2006 23:00:15
if we can put patches in a/the rebol.r file (and its actually read, which is not always the case right now) then this does handle patching code at large.
But if we only want to patch stuff in one file, I guess loading modules should simply inherit (clone) the script's context when it is loaded. this way, if you define it early on, those modules will be adapted. you could then even change a word's definition and open a second module, assigning different privileges to different tasks within your app.
If we can re-load modules, then it would simply be re-bound at that point in time, but any internal module data is also reset... so there is no unexpected/dangerous behaviour.
I don't see the real-world use for changing the definition within a loaded module. Its going to be flawed in one way or another anyways. simply because we cannot really trap a word, we can store functions without words, 'CHANGE them, rename them... and then, there are cases where you use save but store a backup... for dialecting... its a big can of worms IMHO... and what's keeping the module from re-defining it internally, again, 5 seconds later...
Volker 8-Sep-2006 7:25:38
Maxim, such changing is a problem for security IMHO. Its much easier to set a security, load a module and freeze it, then to allow it later to be changed from the outside. Much more rules needed IMHO.
The way i would do it: Allow to add code to all module-source (temporarily), then rebuild the whole thing from ground up, as in a real boot. Setting things right the first time instead of changing them later. Then a module has limits on what it can do, a limit on who can add code, and a fixed place in the boot-oder.
Its still possible to export an explicit 'do which can runs its arguments in the modules context, if that is really needed.
Anton Rolls 18-Sep-2006 10:55:46
I also see the system-wide "re-set" idea as problematic.