In C, redefining a function associated with another compilation unit between hard-to-reach ones. It all comes down to the following: when a program is compiled, each imported or exported symbol is listed in the symbol table. You can look at this table using GPL systems, so Linux objdump -T $EXECUTABLE_OR_BINARYOBJECT , on Unix and Linux nm $EXECUTABLE_OR_BINARYOBJECT
The linker then uses this table to identify the parts that will be glued together. First, he reads in the symbol table of each binary and library library provided, fills the symbol table where to look for them, and then associates them with empty symbol import slots (I strongly recommend that every programmer read the linker source code, or better yet, write it - he is very training).
The standard library or libm specifically provides the sin symbol, among other things. Now imagine a program in which the compilation part also exports a symbol named sin . The linker only has symbol names to work with; if a collision occurs, what happens is highly dependent on the linker, but what you can be sure of is that this is unlikely to be desirable.
C ++ prevents namespace conflicts by changing characters. The changed name contains information about the type and namespace. However, if in a C ++ program two characters with the same name and type, without or inside the same namespace, are defined in several compilation units, the same problem exists.
Fortran is even older than C. Like C, there are no namespaces, and again only character names are used for binding. So the problem is the same, at least for Fortran77.
Objective-C is technically C with a message-based object system on top; the same binding rules. Objective-C ++ refers to Objective-C, since C ++ does C.
In Java, every character exists in this class and is thus surrounded by a namespace. Since classes are tied to compilation units, this also prevents namespace conflicts, of course. But it also makes it impossible to redefine things in Java in a straightforward way (although crazy things can be done at the bytecode level).
In Python, external functions are accessed by modules. If you write import spamneggs , then what actually happens is that the special function __import__ is called, and the result is stored as a variable with the name of the modules. The type of this variable is module , but technically it's just a reference to an illustrious dictionary similar to classes. If you write
import math origsin = math.sin() def mysin(v): return origsin(v) math.sin = mysin
it happens that you take a copy of the original math.sin and overwrite math.sin with your override. Since instances of modules are shared by the interpreter, unless the sandbox is used, this overrides sin transparent, unremovable way for the entire program. This allows you to choose: either override for the entire program, or use the sandbox to save local data.
I am not such an experienced ruby ββencoder, so I can not tell you about it.
In Lisp and Scheme, you can do much cooler things than just overriding, but everything you do has only local effects without side effects. In Haskell, this is similar.