Break OO privacy: Difference between revisions

Content added Content deleted
(Added Lua.)
m (syntax highlighting fixup automation)
Line 33: Line 33:
Similar to C++, ABAP allows the declaration of friends which can be both classes and interfaces. All subclasses of friend classes are automatically friends of the source class. For example if classA (source) has classB as a friend and classC is a subclass of classB then classC is a friend of classA. Similarly all implementing classes of friend interfaces are friends of the source class. Also all interfaces which contain the befriended interface as a component are friends of the source class.
Similar to C++, ABAP allows the declaration of friends which can be both classes and interfaces. All subclasses of friend classes are automatically friends of the source class. For example if classA (source) has classB as a friend and classC is a subclass of classB then classC is a friend of classA. Similarly all implementing classes of friend interfaces are friends of the source class. Also all interfaces which contain the befriended interface as a component are friends of the source class.


<lang ABAP>class friendly_class definition deferred.
<syntaxhighlight lang=ABAP>class friendly_class definition deferred.


class my_class definition friends friendly_class .
class my_class definition friends friendly_class .
Line 74: Line 74:


endclass.
endclass.
</syntaxhighlight>
</lang>


=={{header|Ada}}==
=={{header|Ada}}==
Line 80: Line 80:
One of the great criticisms of Pascal was "there is no escape". The reason was that sometimes you have to convert the incompatible. We start with a package, which defines the data type which holds the secret.
One of the great criticisms of Pascal was "there is no escape". The reason was that sometimes you have to convert the incompatible. We start with a package, which defines the data type which holds the secret.


<lang Ada>package OO_Privacy is
<syntaxhighlight lang=Ada>package OO_Privacy is


type Confidential_Stuff is tagged private;
type Confidential_Stuff is tagged private;
Line 89: Line 89:
Password: Password_Type := "default!"; -- the "secret"
Password: Password_Type := "default!"; -- the "secret"
end record;
end record;
end OO_Privacy;</lang>
end OO_Privacy;</syntaxhighlight>


When we later define an object C of type Confidential_Stuff, we can't read read the password stored in C -- except by breaking / bypassing OO privacy rules.
When we later define an object C of type Confidential_Stuff, we can't read read the password stored in C -- except by breaking / bypassing OO privacy rules.
Line 97: Line 97:
One way to read the password is by using the generic function Unchecked_Conversion:
One way to read the password is by using the generic function Unchecked_Conversion:


<lang Ada>with OO_Privacy, Ada.Unchecked_Conversion, Ada.Text_IO;
<syntaxhighlight lang=Ada>with OO_Privacy, Ada.Unchecked_Conversion, Ada.Text_IO;


procedure OO_Break_Privacy is
procedure OO_Break_Privacy is
Line 112: Line 112:
begin
begin
Ada.Text_IO.Put_Line("The secret password is """ & Hack(C).Password & """");
Ada.Text_IO.Put_Line("The secret password is """ & Hack(C).Password & """");
end OO_Break_Privacy;</lang>
end OO_Break_Privacy;</syntaxhighlight>


The output shows that C holds, surprise, surprise, the default password:
The output shows that C holds, surprise, surprise, the default password:
Line 122: Line 122:
Another way to bypass privacy is using a child package. Ada child packages have access to their parents' private data structures (somewhat similar to "friends" in C++"):
Another way to bypass privacy is using a child package. Ada child packages have access to their parents' private data structures (somewhat similar to "friends" in C++"):


<lang Ada>package OO_Privacy.Friend is -- child package of OO.Privacy
<syntaxhighlight lang=Ada>package OO_Privacy.Friend is -- child package of OO.Privacy
function Get_Password(Secret: Confidential_Stuff) return String;
function Get_Password(Secret: Confidential_Stuff) return String;
end OO_Privacy.Friend;</lang>
end OO_Privacy.Friend;</syntaxhighlight>


<lang Ada>package body OO_Privacy.Friend is -- implementation of the child package
<syntaxhighlight lang=Ada>package body OO_Privacy.Friend is -- implementation of the child package
function Get_Password(Secret: Confidential_Stuff) return String is
function Get_Password(Secret: Confidential_Stuff) return String is
(Secret.Password);
(Secret.Password);
end OO_Privacy.Friend;</lang>
end OO_Privacy.Friend;</syntaxhighlight>


Now here is the program that uses the child package, to read the secret:
Now here is the program that uses the child package, to read the secret:


<lang Ada>with OO_Privacy.Friend, Ada.Text_IO;
<syntaxhighlight lang=Ada>with OO_Privacy.Friend, Ada.Text_IO;
procedure Bypass_OO_Privacy is
procedure Bypass_OO_Privacy is
Line 147: Line 147:
OO_Privacy.Friend.Get_Password(C) &
OO_Privacy.Friend.Get_Password(C) &
"""");
"""");
end Bypass_OO_Privacy;</lang>
end Bypass_OO_Privacy;</syntaxhighlight>


Once again, we have been too lazy to overwrite the default password:
Once again, we have been too lazy to overwrite the default password:
Line 156: Line 156:


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>using System;
<syntaxhighlight lang=csharp>using System;
using System.Reflection;
using System.Reflection;


Line 173: Line 173:
Console.WriteLine(answer);
Console.WriteLine(answer);
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<lang>42</lang>
<syntaxhighlight lang=text>42</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
Line 181: Line 181:
C++ has the 'friend' keyword to indicate that one class should have access to the private data of another. Here's a simple use case. (Please note that this code is not thread-safe.)
C++ has the 'friend' keyword to indicate that one class should have access to the private data of another. Here's a simple use case. (Please note that this code is not thread-safe.)


<lang cpp>#include <iostream>
<syntaxhighlight lang=cpp>#include <iostream>


class CWidget; // Forward-declare that we have a class named CWidget.
class CWidget; // Forward-declare that we have a class named CWidget.
Line 247: Line 247:
delete pWidget3;
delete pWidget3;
delete pWidget2;
delete pWidget2;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<lang text>Widget spawning. There are now 1 Widgets instanciated.
<syntaxhighlight lang=text>Widget spawning. There are now 1 Widgets instanciated.
Widget spawning. There are now 2 Widgets instanciated.
Widget spawning. There are now 2 Widgets instanciated.
Widget dieing. There are now 1 Widgets instanciated.
Widget dieing. There are now 1 Widgets instanciated.
Widget spawning. There are now 2 Widgets instanciated.
Widget spawning. There are now 2 Widgets instanciated.
Widget dieing. There are now 1 Widgets instanciated.
Widget dieing. There are now 1 Widgets instanciated.
Widget dieing. There are now 0 Widgets instanciated.</lang>
Widget dieing. There are now 0 Widgets instanciated.</syntaxhighlight>


Without the "friend" mechanism, it's still possible to meaningfully modify any member in another class, as long as you know that member's address in memory, and its type. Here's the same program as above, but using a pointer to m_uicount, rather a reference to the factory:
Without the "friend" mechanism, it's still possible to meaningfully modify any member in another class, as long as you know that member's address in memory, and its type. Here's the same program as above, but using a pointer to m_uicount, rather a reference to the factory:


<lang cpp>#include <iostream>
<syntaxhighlight lang=cpp>#include <iostream>


class CWidget; // Forward-declare that we have a class named CWidget.
class CWidget; // Forward-declare that we have a class named CWidget.
Line 323: Line 323:
delete pWidget3;
delete pWidget3;
delete pWidget2;
delete pWidget2;
}</lang>
}</syntaxhighlight>


=={{header|Clojure}}==
=={{header|Clojure}}==
You can use the var-quote macro to get values from private variables. Here's an example of a variable 'priv' marked private in namespace 'a':
You can use the var-quote macro to get values from private variables. Here's an example of a variable 'priv' marked private in namespace 'a':
<lang clojure>
<syntaxhighlight lang=clojure>
(ns a)
(ns a)
(def ^:private priv :secret)
(def ^:private priv :secret)
Line 335: Line 335:
user=> @#'a/priv ; succeeds
user=> @#'a/priv ; succeeds
:secret
:secret
</syntaxhighlight>
</lang>


Clojure can also access Java private variables with the same strategy that Java uses. As a convenience, use the [http://clojuredocs.org/clojure_contrib/clojure.contrib.reflect/get-field get-field] function from clojure.contrib.reflect. Here's an example of grabbing the private field "serialVersionUID" from java.lang.Double:
Clojure can also access Java private variables with the same strategy that Java uses. As a convenience, use the [http://clojuredocs.org/clojure_contrib/clojure.contrib.reflect/get-field get-field] function from clojure.contrib.reflect. Here's an example of grabbing the private field "serialVersionUID" from java.lang.Double:
<lang clojure>
<syntaxhighlight lang=clojure>
user=> (get-field Double "serialVersionUID" (Double/valueOf 1.0))
user=> (get-field Double "serialVersionUID" (Double/valueOf 1.0))
-9172774392245257468
-9172774392245257468
</syntaxhighlight>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 358: Line 358:
A symbol can be present in more than one package, such that it can be internal in some of them, and external in others.
A symbol can be present in more than one package, such that it can be internal in some of them, and external in others.


<lang lisp>(defpackage :funky
<syntaxhighlight lang=lisp>(defpackage :funky
;; only these symbols are public
;; only these symbols are public
(:export :widget :get-wobbliness)
(:export :widget :get-wobbliness)
Line 402: Line 402:
;; even read and evaluated. The symbol is internal and so cannot be used.
;; even read and evaluated. The symbol is internal and so cannot be used.
(format t "wobbliness: ~a~%" (slot-value *w* 'funky:wobbliness))
(format t "wobbliness: ~a~%" (slot-value *w* 'funky:wobbliness))
</syntaxhighlight>
</lang>


{{Out}} using CLISP:
{{Out}} using CLISP:
Line 416: Line 416:


breakingprivacy.d:
breakingprivacy.d:
<lang D>module breakingprivacy;
<syntaxhighlight lang=D>module breakingprivacy;


struct Foo
struct Foo
Line 426: Line 426:
string str;
string str;
float f;
float f;
}</lang>
}</syntaxhighlight>


app.d:
app.d:
<lang D>import std.stdio;
<syntaxhighlight lang=D>import std.stdio;
import breakingprivacy;
import breakingprivacy;


Line 444: Line 444:
__traits(getMember, foo, "str") = "Not so private anymore!";
__traits(getMember, foo, "str") = "Not so private anymore!";
writeln("Modified foo: ", foo);
writeln("Modified foo: ", foo);
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
<lang text>Foo([1, 2, 3], 42, "Hello World!", 3.14)
<syntaxhighlight lang=text>Foo([1, 2, 3], 42, "Hello World!", 3.14)
foo.x = 42
foo.x = 42
Modified foo: Foo([1, 2, 3], 42, "Not so private anymore!", 3.14)</lang>
Modified foo: Foo([1, 2, 3], 42, "Not so private anymore!", 3.14)</syntaxhighlight>


=={{header|E}}==
=={{header|E}}==
Line 459: Line 459:
=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
{{trans|C#}}
{{trans|C#}}
<lang fsharp>open System
<syntaxhighlight lang=fsharp>open System
open System.Reflection
open System.Reflection


Line 474: Line 474:
let answer = fieldInfo.GetValue(myInstance)
let answer = fieldInfo.GetValue(myInstance)
printfn "%s = %A" (answer.GetType().ToString()) answer
printfn "%s = %A" (answer.GetType().ToString()) answer
0</lang>
0</syntaxhighlight>
{{out}}
{{out}}
<pre>System.Int32 = 42</pre>
<pre>System.Int32 = 42</pre>
Line 483: Line 483:
This example uses the private word ''sequence/tester'' from the vocabulary ''sets.private''. It tries to count the elements in an intersection of two sets.
This example uses the private word ''sequence/tester'' from the vocabulary ''sets.private''. It tries to count the elements in an intersection of two sets.


<lang factor>( scratchpad ) USING: sets sets.private ;
<syntaxhighlight lang=factor>( scratchpad ) USING: sets sets.private ;
( scratchpad ) { 1 2 3 } { 1 2 4 } sequence/tester count .
( scratchpad ) { 1 2 3 } { 1 2 4 } sequence/tester count .
2</lang>
2</syntaxhighlight>


There is better way to do the same, without any private words.
There is better way to do the same, without any private words.


<lang factor>( scratchpad ) USE: sets
<syntaxhighlight lang=factor>( scratchpad ) USE: sets
( scratchpad ) { 1 2 3 } { 1 2 4 } intersect length .
( scratchpad ) { 1 2 3 } { 1 2 4 } intersect length .
2</lang>
2</syntaxhighlight>


=={{header|Forth}}==
=={{header|Forth}}==
Line 499: Line 499:
Needs the FMS-SI (single inheritance) library code located here:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
http://soton.mpeforth.com/flag/fms/index.html
<lang forth>include FMS-SI.f
<syntaxhighlight lang=forth>include FMS-SI.f


99 value x \ create a global variable named x
99 value x \ create a global variable named x
Line 516: Line 516:
50 .. f1.x ! \ use the dot parser to access the private x without a message
50 .. f1.x ! \ use the dot parser to access the private x without a message
f1 print \ 50
f1 print \ 50
</syntaxhighlight>
</lang>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
Line 522: Line 522:


However, as usual, macros come to the rescue and one can easily access non-public members by the simple expedient (or, if you prefer, 'dirty hack') of redefining the Private and Protected keywords to mean Public:
However, as usual, macros come to the rescue and one can easily access non-public members by the simple expedient (or, if you prefer, 'dirty hack') of redefining the Private and Protected keywords to mean Public:
<lang freebasic>'FB 1.05.0 Win64
<syntaxhighlight lang=freebasic>'FB 1.05.0 Win64


#Undef Private
#Undef Private
Line 542: Line 542:
Print
Print
Print "Press any key to quit"
Print "Press any key to quit"
Sleep</lang>
Sleep</syntaxhighlight>


{{out}}
{{out}}
Line 555: Line 555:
A relevant Go Blog article is
A relevant Go Blog article is
[http://blog.golang.org/laws-of-reflection The Laws of Reflection].
[http://blog.golang.org/laws-of-reflection The Laws of Reflection].
<lang go>package main
<syntaxhighlight lang=go>package main


import (
import (
Line 642: Line 642:
_, err := r.ReadByte()
_, err := r.ReadByte()
fmt.Println("bufio.ReadByte returned error:", err)
fmt.Println("bufio.ReadByte returned error:", err)
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 664: Line 664:


Note: Unicon can be translated via a command line switch into icon which allows for classes to be shared with Icon code (assuming no other incompatibilities exist).
Note: Unicon can be translated via a command line switch into icon which allows for classes to be shared with Icon code (assuming no other incompatibilities exist).
<lang unicon>link printf
<syntaxhighlight lang=unicon>link printf


procedure main()
procedure main()
Line 680: Line 680:
printf("foo var1=%i, var2=%i, var3=%i\n",var1,var2,var3)
printf("foo var1=%i, var2=%i, var3=%i\n",var1,var2,var3)
end
end
end</lang>
end</syntaxhighlight>


{{libheader|Icon Programming Library}}
{{libheader|Icon Programming Library}}
Line 700: Line 700:
=={{header|Java}}==
=={{header|Java}}==
Private fields (and in general all members) of a Java class can be accessed via reflection, but must pass a security check in order to do so. There are two such security checks, one for discovering the field at all, and another for granting access to it in order to be able to read and write it. (This in turn means that trusted applications can do this — it is in fact a mechanism used by important frameworks like Spring — but untrusted applets cannot.)
Private fields (and in general all members) of a Java class can be accessed via reflection, but must pass a security check in order to do so. There are two such security checks, one for discovering the field at all, and another for granting access to it in order to be able to read and write it. (This in turn means that trusted applications can do this — it is in fact a mechanism used by important frameworks like Spring — but untrusted applets cannot.)
<lang java>import java.lang.reflect.*;
<syntaxhighlight lang=java>import java.lang.reflect.*;
class Example {
class Example {
Line 728: Line 728:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 737: Line 737:


(Note: somewhere between Java 8 and Java 11 this stopped working because the <code>value</code> field of <code>String</code> is <code>final</code>. The reflective access is still possible, but changing a final field isn't.)
(Note: somewhere between Java 8 and Java 11 this stopped working because the <code>value</code> field of <code>String</code> is <code>final</code>. The reflective access is still possible, but changing a final field isn't.)
<lang Java>import java.lang.reflect.*;
<syntaxhighlight lang=Java>import java.lang.reflect.*;
public class BreakString{
public class BreakString{
public static void main(String... args) throws Exception{
public static void main(String... args) throws Exception{
Line 747: Line 747:
}
}
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 760: Line 760:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
For tasks such as this, reflection is your friend:
For tasks such as this, reflection is your friend:
<lang scala>import kotlin.reflect.full.declaredMemberProperties
<syntaxhighlight lang=scala>import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.isAccessible


Line 775: Line 775:
println("${prop.name} -> ${prop.get(tbb)}")
println("${prop.name} -> ${prop.get(tbb)}")
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 786: Line 786:


In the following example, a prototype is used for simplicity.
In the following example, a prototype is used for simplicity.
<lang logtalk>:- object(foo).
<syntaxhighlight lang=logtalk>:- object(foo).


% be sure that context switching calls are allowed
% be sure that context switching calls are allowed
Line 797: Line 797:
bar(3).
bar(3).


:- end_object.</lang>
:- end_object.</syntaxhighlight>
After compiling and loading the above object, we can use the following query to access the private method:
After compiling and loading the above object, we can use the following query to access the private method:
<lang logtalk>| ?- foo<<bar(X).
<syntaxhighlight lang=logtalk>| ?- foo<<bar(X).
X = 1 ;
X = 1 ;
X = 2 ;
X = 2 ;
X = 3
X = 3
true</lang>
true</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
Line 811: Line 811:
These can be accessed indirectly through the [https://www.lua.org/manual/5.1/manual.html#5.9 debug library].
These can be accessed indirectly through the [https://www.lua.org/manual/5.1/manual.html#5.9 debug library].


<lang Lua>local function Counter()
<syntaxhighlight lang=Lua>local function Counter()
-- These two variables are "private" to this function and can normally
-- These two variables are "private" to this function and can normally
-- only be accessed from within this scope, including by any function
-- only be accessed from within this scope, including by any function
Line 840: Line 840:
break
break
end
end
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 851: Line 851:
=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
We want to read two private variables, and change values without using a public method (a module or a function), and without attach a temporary method (we can do that in M2000). There is a variant in READ statemend to set references from group members (for variables and arrays, and objects) to names with a reference for each. So using these names (here in the exaample K, M) we can read and write private variables.
We want to read two private variables, and change values without using a public method (a module or a function), and without attach a temporary method (we can do that in M2000). There is a variant in READ statemend to set references from group members (for variables and arrays, and objects) to names with a reference for each. So using these names (here in the exaample K, M) we can read and write private variables.
<lang M2000 Interpreter>
<syntaxhighlight lang=M2000 Interpreter>
Module CheckIt {
Module CheckIt {
Group Alfa {
Group Alfa {
Line 872: Line 872:
}
}
CheckIt
CheckIt
</syntaxhighlight>
</lang>


=={{header|Nim}}==
=={{header|Nim}}==
File oo.nim:
File oo.nim:
<lang nim>type Foo* = object
<syntaxhighlight lang=nim>type Foo* = object
a: string
a: string
b: string
b: string
Line 882: Line 882:


proc createFoo*(a, b, c): Foo =
proc createFoo*(a, b, c): Foo =
Foo(a: a, b: b, c: c)</lang>
Foo(a: a, b: b, c: c)</syntaxhighlight>
By not adding a <code>*</code> to <code>Foo</code>'s members we don't export them. When we import this module we can't use them directly:
By not adding a <code>*</code> to <code>Foo</code>'s members we don't export them. When we import this module we can't use them directly:
<lang nim>var x = createFoo("this a", "this b", 12)
<syntaxhighlight lang=nim>var x = createFoo("this a", "this b", 12)


echo x.a # compile time error</lang>
echo x.a # compile time error</syntaxhighlight>
The easiest way to get a debug view of any data:
The easiest way to get a debug view of any data:
<lang nim>echo repr(x)</lang>
<syntaxhighlight lang=nim>echo repr(x)</syntaxhighlight>
Output:
Output:
<pre>[a = 0x7f6bb87a7050"this a",
<pre>[a = 0x7f6bb87a7050"this a",
Line 894: Line 894:
c = 12]</pre>
c = 12]</pre>
More fine-grained:
More fine-grained:
<lang nim>import typeinfo
<syntaxhighlight lang=nim>import typeinfo


for key, val in fields(toAny(x)):
for key, val in fields(toAny(x)):
Line 904: Line 904:
echo " is an integer with value: ", val.getBiggestInt
echo " is an integer with value: ", val.getBiggestInt
else:
else:
echo " is an unknown with value: ", val.repr</lang>
echo " is an unknown with value: ", val.repr</syntaxhighlight>
Output:
Output:
<pre>Key a
<pre>Key a
Line 919: Line 919:
One solution is to use Key-Value Coding. It treats properties and instance variables as "keys" that you can get and set using key-value coding methods.
One solution is to use Key-Value Coding. It treats properties and instance variables as "keys" that you can get and set using key-value coding methods.


<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>


@interface Example : NSObject {
@interface Example : NSObject {
Line 954: Line 954:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 964: Line 964:
Another solution is to use a category to add methods to the class (you can have categories in your code modify any class, even classes compiled by someone else, including system classes). Since the new method is in the class, it can use the class's private instance variables with no problem.
Another solution is to use a category to add methods to the class (you can have categories in your code modify any class, even classes compiled by someone else, including system classes). Since the new method is in the class, it can use the class's private instance variables with no problem.


<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>


@interface Example : NSObject {
@interface Example : NSObject {
Line 1,013: Line 1,013:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,023: Line 1,023:
Finally, you can access the instance variable directly using runtime functions.
Finally, you can access the instance variable directly using runtime functions.


<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/runtime.h>


Line 1,060: Line 1,060:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,077: Line 1,077:
The reader is advised to stop reading here.
The reader is advised to stop reading here.


<lang ocaml>class point x y =
<syntaxhighlight lang=ocaml>class point x y =
object
object
val mutable x = x
val mutable x = x
Line 1,109: Line 1,109:
Printf.printf "Broken coord: (%d, %d)\n" x y;
Printf.printf "Broken coord: (%d, %d)\n" x y;
evil_reset p
evil_reset p
p#print</lang>
p#print</syntaxhighlight>


{{out}}
{{out}}
Line 1,126: Line 1,126:
=={{header|Perl}}==
=={{header|Perl}}==
Perl's object model does not enforce privacy. An object is just a blessed reference, and a blessed reference can be dereferenced just like an ordinary reference.
Perl's object model does not enforce privacy. An object is just a blessed reference, and a blessed reference can be dereferenced just like an ordinary reference.
<lang perl>package Foo;
<syntaxhighlight lang=perl>package Foo;
sub new {
sub new {
my $class = shift;
my $class = shift;
Line 1,140: Line 1,140:
package main;
package main;
my $foo = Foo->new();
my $foo = Foo->new();
print "$_\n" for $foo->get_bar(), $foo->{_bar};</lang>
print "$_\n" for $foo->get_bar(), $foo->{_bar};</syntaxhighlight>
{{out}}
{{out}}
<pre>I am ostensibly private
<pre>I am ostensibly private
Line 1,150: Line 1,150:
We can easily break that privacy mechanism via low-level routines with the required simulated/fake context,<br>
We can easily break that privacy mechanism via low-level routines with the required simulated/fake context,<br>
and at the same time be reasonably confident that no-one is ever going to manage to achieve that by accident.
and at the same time be reasonably confident that no-one is ever going to manage to achieve that by accident.
<!--<lang Phix>(notonline)-->
<!--<syntaxhighlight lang=Phix>(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (no class under p2js)</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (no class under p2js)</span>
<span style="color: #008080;">class</span> <span style="color: #000000;">test</span>
<span style="color: #008080;">class</span> <span style="color: #000000;">test</span>
Line 1,167: Line 1,167:
<span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">store_field</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"msg"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"this breaks privacy"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ctx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">store_field</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"msg"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"this breaks privacy"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ctx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
<small>(Obviously you could inline the ctx values rather than create a separate constant.)</small>
<small>(Obviously you could inline the ctx values rather than create a separate constant.)</small>
{{out}}
{{out}}
Line 1,180: Line 1,180:


{{works with|PHP|5.1}}
{{works with|PHP|5.1}}
<lang php><?php
<syntaxhighlight lang=php><?php
class SimpleClass {
class SimpleClass {
private $answer = "hello\"world\nforever :)";
private $answer = "hello\"world\nforever :)";
Line 1,198: Line 1,198:


$new_class = eval($class_content);
$new_class = eval($class_content);
echo $new_class['answer'];</lang>
echo $new_class['answer'];</syntaxhighlight>


Another way commonly used to access private and protected variables in PHP is to cast the object to an array. It's probably unintentional though looking on how casted array contains null bytes (probably "private" mark). This works unless a magic method for the cast operation is implemented:
Another way commonly used to access private and protected variables in PHP is to cast the object to an array. It's probably unintentional though looking on how casted array contains null bytes (probably "private" mark). This works unless a magic method for the cast operation is implemented:
Line 1,204: Line 1,204:
{{works with|PHP|4.x}}
{{works with|PHP|4.x}}
{{works with|PHP|5.x}}
{{works with|PHP|5.x}}
<lang php><?php
<syntaxhighlight lang=php><?php
class SimpleClass {
class SimpleClass {
private $answer = 42;
private $answer = 42;
Line 1,211: Line 1,211:
$class = new SimpleClass;
$class = new SimpleClass;
$classvars = (array)$class;
$classvars = (array)$class;
echo $classvars["\0SimpleClass\0answer"];</lang>
echo $classvars["\0SimpleClass\0answer"];</syntaxhighlight>


{{works with|PHP|5.3}}
{{works with|PHP|5.3}}
Since php 5.3, one can easily read and write any protected and private member in a object via reflection.
Since php 5.3, one can easily read and write any protected and private member in a object via reflection.
<lang php><?php
<syntaxhighlight lang=php><?php
class fragile {
class fragile {
private $foo = 'bar';
private $foo = 'bar';
Line 1,226: Line 1,226:
$rp->setValue($fragile, 'haxxorz!');
$rp->setValue($fragile, 'haxxorz!');
var_dump($rp->getValue($fragile));
var_dump($rp->getValue($fragile));
var_dump($fragile);</lang>
var_dump($fragile);</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,240: Line 1,240:
PicoLisp uses [http://software-lab.de/doc/ref.html#transient "transient symbols"] for variables, functions, methods etc. inaccessible from other parts of the program. Lexically, a transient symbol is enclosed by double quotes.
PicoLisp uses [http://software-lab.de/doc/ref.html#transient "transient symbols"] for variables, functions, methods etc. inaccessible from other parts of the program. Lexically, a transient symbol is enclosed by double quotes.
The only way to access a transient symbol outside its namespace is to search for its name in other (public) structures. This is done by the '[http://software-lab.de/doc/refL.html#loc loc]' function.
The only way to access a transient symbol outside its namespace is to search for its name in other (public) structures. This is done by the '[http://software-lab.de/doc/refL.html#loc loc]' function.
<lang PicoLisp>(class +Example)
<syntaxhighlight lang=PicoLisp>(class +Example)
# "_name"
# "_name"


Line 1,251: Line 1,251:
(====) # Close transient scope
(====) # Close transient scope


(setq Foo (new '(+Example) "Eric"))</lang>
(setq Foo (new '(+Example) "Eric"))</syntaxhighlight>
Test:
Test:
<lang PicoLisp>: (string> Foo) # Access via method call
<syntaxhighlight lang=PicoLisp>: (string> Foo) # Access via method call
-> "Hello, I am Eric"
-> "Hello, I am Eric"


Line 1,272: Line 1,272:


: (get Foo (loc "_name" +Example))
: (get Foo (loc "_name" +Example))
-> "Edith"</lang>
-> "Edith"</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
Python isn't heavily into private class names. Although private class names can be defined by using a double underscore at the start of the name, such names are accessible as they are mangled into the original name preceded by the name of its class as shown in this example:
Python isn't heavily into private class names. Although private class names can be defined by using a double underscore at the start of the name, such names are accessible as they are mangled into the original name preceded by the name of its class as shown in this example:
<lang python>>>> class MyClassName:
<syntaxhighlight lang=python>>>> class MyClassName:
__private = 123
__private = 123
non_private = __private * 2
non_private = __private * 2
Line 1,291: Line 1,291:
>>> mine._MyClassName__private
>>> mine._MyClassName__private
123
123
>>> </lang>
>>> </syntaxhighlight>


=={{header|Raku}}==
=={{header|Raku}}==
Line 1,297: Line 1,297:
{{works with|Rakudo|2015.12}}
{{works with|Rakudo|2015.12}}
We may call into the MOP (Meta-Object Protocol) via the <tt>.^</tt> operator, and the MOP knows all about the object, including any supposedly private bits. We ask for its attributes, find the correct one, and get its value.
We may call into the MOP (Meta-Object Protocol) via the <tt>.^</tt> operator, and the MOP knows all about the object, including any supposedly private bits. We ask for its attributes, find the correct one, and get its value.
<lang perl6>class Foo {
<syntaxhighlight lang=raku line>class Foo {
has $!shyguy = 42;
has $!shyguy = 42;
}
}
my Foo $foo .= new;
my Foo $foo .= new;


say $foo.^attributes.first('$!shyguy').get_value($foo);</lang>
say $foo.^attributes.first('$!shyguy').get_value($foo);</syntaxhighlight>
{{out}}
{{out}}
<pre>42</pre>
<pre>42</pre>
Line 1,308: Line 1,308:
=={{header|Ruby}}==
=={{header|Ruby}}==
Ruby lets you redefine great parts of the object model at runtime and provides several methods to do so conveniently. For a list of all available methods look up the documentation of <code>Object</code> and <code>Module</code> or call informative methods at runtime (<code>puts Object.methods</code>).
Ruby lets you redefine great parts of the object model at runtime and provides several methods to do so conveniently. For a list of all available methods look up the documentation of <code>Object</code> and <code>Module</code> or call informative methods at runtime (<code>puts Object.methods</code>).
<lang ruby>
<syntaxhighlight lang=ruby>
class Example
class Example
def initialize
def initialize
Line 1,326: Line 1,326:
p example.instance_variable_set :@private_data, 42 # => 42
p example.instance_variable_set :@private_data, 42 # => 42
p example.instance_variable_get :@private_data # => 42
p example.instance_variable_get :@private_data # => 42
</syntaxhighlight>
</lang>


=={{header|Scala}}==
=={{header|Scala}}==
{{libheader|Scala}}<lang scala>class Example(private var name: String) {
{{libheader|Scala}}<syntaxhighlight lang=scala>class Example(private var name: String) {
override def toString = s"Hello, I am $name"
override def toString = s"Hello, I am $name"
}
}
Line 1,341: Line 1,341:
field.set(foo, "Edith")
field.set(foo, "Edith")
println(foo)
println(foo)
}</lang>
}</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
Sidef's object model does not enforce privacy, but it allows storing private attributes inside the container of an object, which is an hash:
Sidef's object model does not enforce privacy, but it allows storing private attributes inside the container of an object, which is an hash:
<lang ruby>class Example {
<syntaxhighlight lang=ruby>class Example {
has public = "foo"
has public = "foo"
method init {
method init {
Line 1,359: Line 1,359:


# Access private attributes
# Access private attributes
say obj{:private}; #=> "secret"</lang>
say obj{:private}; #=> "secret"</syntaxhighlight>


=={{header|Swift}}==
=={{header|Swift}}==
Swift reflection provides a Collection of label-value pairs for struct properties
Swift reflection provides a Collection of label-value pairs for struct properties
<lang Swift>struct Example {
<syntaxhighlight lang=Swift>struct Example {
var notSoSecret = "Hello!"
var notSoSecret = "Hello!"
private var secret = 42
private var secret = 42
Line 1,374: Line 1,374:
print("Value of the secret is \(secret)")
print("Value of the secret is \(secret)")
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>Value of the secret is 42</pre>
<pre>Value of the secret is 42</pre>
Line 1,380: Line 1,380:
=={{header|Tcl}}==
=={{header|Tcl}}==
Tcl's object properties are just variables in the a per-instance namespace; all that's required to get hold of them is to discover the name of the namespace concerned:
Tcl's object properties are just variables in the a per-instance namespace; all that's required to get hold of them is to discover the name of the namespace concerned:
<lang tcl>package require Tcl 8.6
<syntaxhighlight lang=tcl>package require Tcl 8.6


oo::class create Example {
oo::class create Example {
Line 1,390: Line 1,390:
$e print
$e print
set [info object namespace $e]::name "Edith"
set [info object namespace $e]::name "Edith"
$e print</lang>{{out}}
$e print</syntaxhighlight>{{out}}
Hello, I am Eric
Hello, I am Eric
Hello, I am Edith
Hello, I am Edith
Line 1,400: Line 1,400:
Like the other .NET languages, VB can use Reflection ([https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection Microsoft docs]).
Like the other .NET languages, VB can use Reflection ([https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection Microsoft docs]).


<lang vbnet>Imports System.Reflection
<syntaxhighlight lang=vbnet>Imports System.Reflection


' MyClass is a VB keyword.
' MyClass is a VB keyword.
Line 1,414: Line 1,414:
Console.WriteLine(answer)
Console.WriteLine(answer)
End Sub
End Sub
End Class</lang>
End Class</syntaxhighlight>


{{out}}
{{out}}
Line 1,423: Line 1,423:


However, there is no such thing as a private method. Although conventionally methods which are not intended to be called from outside the class are suffixed with an underscore, this doesn't prevent anyone from accessing them as the following example shows.
However, there is no such thing as a private method. Although conventionally methods which are not intended to be called from outside the class are suffixed with an underscore, this doesn't prevent anyone from accessing them as the following example shows.
<lang ecmascript>class Safe {
<syntaxhighlight lang=ecmascript>class Safe {
construct new() { _safe = 42 } // the field _safe is private
construct new() { _safe = 42 } // the field _safe is private
safe { _safe } // provides public access to field
safe { _safe } // provides public access to field
Line 1,432: Line 1,432:
var s = Safe.new()
var s = Safe.new()
var a = [s.safe, s.doubleSafe, s.notSoSafe_]
var a = [s.safe, s.doubleSafe, s.notSoSafe_]
for (e in a) System.print(e)</lang>
for (e in a) System.print(e)</syntaxhighlight>


{{out}}
{{out}}
Line 1,443: Line 1,443:
=={{header|zkl}}==
=={{header|zkl}}==
In zkl, privacy is more convention than enforced (unlike const or protected).
In zkl, privacy is more convention than enforced (unlike const or protected).
<lang zkl>class C{var [private] v; fcn [private] f{123} class [private] D {}}
<syntaxhighlight lang=zkl>class C{var [private] v; fcn [private] f{123} class [private] D {}}
C.v; C.f; C.D; // all generate NotFoundError exceptions
C.v; C.f; C.D; // all generate NotFoundError exceptions
However:
However:
Line 1,449: Line 1,449:
C.fcns[1]() //-->123
C.fcns[1]() //-->123
C.classes //-->L(Class(D))
C.classes //-->L(Class(D))
C.vars //-->L(L("",Void)) (name,value) pairs</lang>
C.vars //-->L(L("",Void)) (name,value) pairs</syntaxhighlight>
In the case of private vars, the name isn't saved.
In the case of private vars, the name isn't saved.