Break OO privacy: Difference between revisions

+OCaml. Please forgive me.
(+OCaml. Please forgive me.)
Line 884:
Hello, I am Edith
</pre>
 
=={{header|OCaml}}==
 
OCaml includes a function called Obj.magic, of type 'a -> 'b.
 
That type alone should tell you that this function is crystallized pure evil. The following is not quite as heroic as peeking at random addresses of memory, but to repeat it does require an understanding of the physical layout of OCaml data.
 
In the following, point's attributes are completely private to the object. They can be revealed with print but can't be directly modified or checked at all. Obj.magic is then used to commit this lie: actually, what was a point object, can be viewed as a four-element tuple of ints. The first two values are meaningless except to OCaml internals and are discarded; the second two values are point's hidden attributes. Then, an even more sinister lie is told that allows us to mutate the point's hidden attributes. Lies of this nature can be used to mutate normally immutable data, which can directly lead to very hard to understand bugs.
 
The reader is advised to stop reading here.
 
<lang ocaml>class point x y =
object
val mutable x = x
val mutable y = y
method print = Printf.printf "(%d, %d)\n" x y
method dance =
x <- x + Random.int 3 - 1;
y <- y + Random.int 3 - 1
end
 
type evil_point {
blah : int;
blah2 : int;
mutable x : int;
mutable y : int;
}
 
let evil_reset p =
let ep = Obj.magic p in
ep.x <- 0;
ep.y <- 0
 
let () =
let p = new point 0 0 in
p#print;
p#dance;
p#print;
p#dance;
p#print;
let (_, _, x, y) : int * int * int * int = Obj.magic p in
Printf.printf "Broken coord: (%d, %d)\n" x y;
evil_reset p
p#print</lang>
 
{{out}}
<pre>(0, 0)
(-1, 0)
(-1, -1)
Broken coord: (-1, -1)
(0, 0)</pre>
 
=={{header|Oforth}}==
Anonymous user