Break OO privacy: Difference between revisions
Content deleted Content added
→{{header|Visual Basic .NET}}: Added VB.NET |
PascalABC.NET |
||
(22 intermediate revisions by 13 users not shown) | |||
Line 1:
{{
Show how to access private or protected members of a class in an object-oriented language from outside an instance of the class, without calling non-private or non-protected members of the class as a proxy.
The intent is to show how a debugger, serializer, or other meta-programming tool might access information that is barred by normal access methods to the object but can nevertheless be accessed from within the language by some provided escape hatch or reflection mechanism.
Line 21 ⟶ 8:
as unidiomatic at best, and poor programming practice at worst.
Nonetheless, if your language intentionally maintains a double-standard for OO privacy, here's where you can show it off.
=={{header|ABAP}}==
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.
<
class my_class definition friends friendly_class .
Line 67 ⟶ 53:
endclass.
</syntaxhighlight>
=={{header|Ada}}==
One of the great criticisms of Pascal was "there is no escape". The reason was that sometimes you have to convert the incompatible.
<
type Confidential_Stuff is tagged private;
Line 83 ⟶ 67:
Password: Password_Type := "default!"; -- the "secret"
end record;
end OO_Privacy;</
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.
One way to read the password is by using the generic function Unchecked_Conversion:
<syntaxhighlight lang="ada">with OO_Privacy, Ada.Unchecked_Conversion, Ada.Text_IO;
procedure OO_Break_Privacy is
Line 102 ⟶ 90:
begin
Ada.Text_IO.Put_Line("The secret password is """ & Hack(C).Password & """");
end OO_Break_Privacy;</
The output shows that C holds, surprise, surprise, the default password:
Line 108 ⟶ 96:
<pre>The secret password is "default!"</pre>
=== Child Packages ===
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++"):
<syntaxhighlight lang="ada">package OO_Privacy.Friend is -- child package of OO.Privacy
function Get_Password(Secret: Confidential_Stuff) return String;
end OO_Privacy.Friend;</syntaxhighlight>
<syntaxhighlight lang="ada">package body OO_Privacy.Friend is -- implementation of the child package
function Get_Password(Secret: Confidential_Stuff) return String is
(Secret.Password);
end OO_Privacy.Friend;</syntaxhighlight>
Now here is the program that uses the child package, to read the secret:
<syntaxhighlight lang="ada">with OO_Privacy.Friend, Ada.Text_IO;
procedure Bypass_OO_Privacy is
C: OO_Privacy.Confidential_Stuff; -- which password is hidden inside C?
begin
Ada.Text_IO.Put_Line("Password: """ &
OO_Privacy.Friend.Get_Password(C) &
"""");
end Bypass_OO_Privacy;</syntaxhighlight>
Once again, we have been too lazy to overwrite the default password:
<pre>Password: "default!"</pre>
In fact, the password has to be the default one, because we cannot change the password. For that purpose, we would have to write a setter procedure, and either include it in the package OO_Privacy, or in a child package of OO_Privacy. (Or we could use Unchecked_Conversion to overwrite the default password -- but that is bad style.)
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
using System.Reflection;
Line 126 ⟶ 150:
Console.WriteLine(answer);
}
}</
{{out}}
<syntaxhighlight lang="text">42</
=={{header|C++}}==
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.)
<
class CWidget; // Forward-declare that we have a class named CWidget.
Line 200 ⟶ 223:
delete pWidget3;
delete pWidget2;
}</
{{out}}
<
Widget spawning. There are now 2 Widgets instanciated.
Widget dieing. There are now 1 Widgets instanciated.
Widget spawning. There are now 2 Widgets instanciated.
Widget dieing. There are now 1 Widgets instanciated.
Widget dieing. There are now 0 Widgets instanciated.</
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:
<
class CWidget; // Forward-declare that we have a class named CWidget.
Line 276 ⟶ 299:
delete pWidget3;
delete pWidget2;
}</
=={{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':
<
(ns a)
(def ^:private priv :secret)
Line 288 ⟶ 310:
user=> @#'a/priv ; succeeds
:secret
</syntaxhighlight>
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:
<
user=> (get-field Double "serialVersionUID" (Double/valueOf 1.0))
-9172774392245257468
</syntaxhighlight>
=={{header|Common Lisp}}==
Line 310 ⟶ 332:
A symbol can be present in more than one package, such that it can be internal in some of them, and external in others.
<
;; only these symbols are public
(:export :widget :get-wobbliness)
Line 354 ⟶ 376:
;; even read and evaluated. The symbol is internal and so cannot be used.
(format t "wobbliness: ~a~%" (slot-value *w* 'funky:wobbliness))
</syntaxhighlight>
{{Out}} using CLISP:
Line 362 ⟶ 384:
*** - READ from #<INPUT BUFFERED FILE-STREAM CHARACTER #P"funky.lisp" @44>:
#<PACKAGE FUNKY> has no external symbol with name "WOBBLINESS"</pre>
=={{header|D}}==
Private members can be accessed by other code in the same module. You can access private members of structs/classes imported from another module using compile time reflection.
breakingprivacy.d:
<syntaxhighlight lang="d">module breakingprivacy;
struct Foo
{
int[] arr;
private:
int x;
string str;
float f;
}</syntaxhighlight>
app.d:
<syntaxhighlight lang="d">import std.stdio;
import breakingprivacy;
void main()
{
auto foo = Foo([1,2,3], 42, "Hello World!", 3.14);
writeln(foo);
// __traits(getMember, obj, name) allows you to access any field of obj given its name
// Reading a private field
writeln("foo.x = ", __traits(getMember, foo, "x"));
// Writing to a private field
__traits(getMember, foo, "str") = "Not so private anymore!";
writeln("Modified foo: ", foo);
}</syntaxhighlight>
{{out}}
<syntaxhighlight lang="text">Foo([1, 2, 3], 42, "Hello World!", 3.14)
foo.x = 42
Modified foo: Foo([1, 2, 3], 42, "Not so private anymore!", 3.14)</syntaxhighlight>
=={{header|E}}==
Line 368 ⟶ 428:
{{improve|E|Show an example of such an evaluator once it is available.}}
=={{header|Ecstasy}}==
In Ecstasy, using the keywords <span style="background-color: #e5e4e2"><tt> public </tt></span>, <span style="background-color: #e5e4e2"><tt> protected </tt></span>, and <span style="background-color: #e5e4e2"><tt> private </tt></span> to mark classes and class members is solely for the benefit of the developer, and not in any way related to security. These keywords help the developer to classify information among three categories: Things that are useful to everyone; things that are useful to further compositions (such as sub-classes and mixins); and things that, were they exposed, would likely to create an ugly mess. <b>Information hiding is about organization, and not about security.</b>
An Ecstasy reference contains both its type (the type of the <i>reference</i> itself, as opposed to the type of the referred-to object, a.k.a. the <i>referent</i>), and the means -- a "pointer" or a "value" -- to refer to the referent. By default, the type of a reference is of the <i>public type</i> of the referent, but it is possible to reveal the referent as any other legal type -- where <i>legal</i> simply means that strong type safety is enforced. This is <b>not</b> a type cast; it is a request to the runtime to provide a different reference to the same underlying object.
Ecstasy security is accomplished by the use of <i>software containers</i>. Code running in a container is always allowed reveal any legal type on any object created within that container, including any object created within sub-containers. However, the runtime will reject any reveal request on any object that was <i>not</i> created within that container.
<syntaxhighlight lang="java">
module BreakOO {
/**
* This is a class with public, protected, and private properties.
*/
class Exposed {
public String pub = "public";
protected String pro = "protected";
private String pri = "private";
@Override
String toString() {
return $"pub={pub.quoted()}, pro={pro.quoted()}, pri={pri.quoted()}";
}
}
void run() {
@Inject Console console;
Exposed expo = new Exposed();
console.print($"before: {expo}");
// you can only access public members from the default reference
expo.pub = $"this was {expo.pub}";
// expo.pro = $"this was {expo.pro}"; <- compiler error
// expo.pri = $"this was {expo.pri}"; <- compiler error
// but you can ask for the protected reference ...
assert (protected Exposed) expoPro := &expo.revealAs((protected Exposed));
expoPro.pro = $"this was {expoPro.pro}";
// expoPro.pri = $"this was {expoPro.pri}"; <- compiler error
// and you can ask for the private reference ...
assert (private Exposed) expoPri := &expo.revealAs((private Exposed));
expoPri.pri = $"this was {expoPri.pri}";
// or you can ask for the underlying struct, which is a passive
// object that contains only the field storage
assert (struct Exposed) expoStr := &expo.revealAs((struct Exposed));
expoStr.pub = $"{expoStr.pub}!!!";
expoStr.pro = $"{expoStr.pro}!!!";
expoStr.pri = $"{expoStr.pri}!!!";
console.print($"after: {expo}");
}
}
</syntaxhighlight>
{{out}}
<pre>
before: pub="public", pro="protected", pri="private"
after: pub="this was public!!!", pro="this was protected!!!", pri="this was private!!!"
</pre>
=={{header|F_Sharp|F#}}==
{{trans|C#}}
<
open System.Reflection
Line 386 ⟶ 506:
let answer = fieldInfo.GetValue(myInstance)
printfn "%s = %A" (answer.GetType().ToString()) answer
0</
{{out}}
<pre>System.Int32 = 42</pre>
=={{header|Factor}}==
From the [http://docs.factorcode.org/content/article-word-search-private.html documentation for private words]: ''"Privacy is not enforced by the system; private words can be called from other vocabularies, and from the listener. However, this should be avoided where possible."''
Line 395 ⟶ 514:
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.
<
( scratchpad ) { 1 2 3 } { 1 2 4 } sequence/tester count .
2</
There is better way to do the same, without any private words.
<
( scratchpad ) { 1 2 3 } { 1 2 4 } intersect length .
2</
=={{header|Forth}}==
{{works with|Forth}}
Line 412 ⟶ 529:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<
99 value x \ create a global variable named x
Line 429 ⟶ 546:
50 .. f1.x ! \ use the dot parser to access the private x without a message
f1 print \ 50
</syntaxhighlight>
=={{header|FreeBASIC}}==
FreeBASIC generally does a good job of maintaining OO privacy as it doesn't support reflection and even its OffsetOf keyword cannot obtain the offset within a user defined type of a private or protected field. You therefore have to guess the offset of a non-public field in order to be able to access it using a raw pointer though this is not generally a difficult task.
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:
<
#Undef Private
Line 455 ⟶ 571:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 461 ⟶ 577:
1 2 3
</pre>
=={{header|Go}}==
Go has a <code>reflect</code> and <code>unsafe</code> package that together can do this.
Line 468 ⟶ 583:
A relevant Go Blog article is
[http://blog.golang.org/laws-of-reflection The Laws of Reflection].
<
import (
Line 555 ⟶ 670:
_, err := r.ReadByte()
fmt.Println("bufio.ReadByte returned error:", err)
}</
{{out}}
<pre>
Line 571 ⟶ 686:
==Icon and {{header|Unicon}}==
Unicon implements object environments with records and supporting procedures for creation, initialization, and methods. The variables in the class environment can be accessed like any other record field. Additionally, with the ''fieldnames'' procedure you can obtain the names of the class variables.
Line 577 ⟶ 691:
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).
<
procedure main()
Line 593 ⟶ 707:
printf("foo var1=%i, var2=%i, var3=%i\n",var1,var2,var3)
end
end</
{{libheader|Icon Programming Library}}
Line 602 ⟶ 716:
var 1 of foo x = 1
foo var1=-1, var2=2, var3=3</pre>
=={{header|J}}==
Line 610 ⟶ 723:
J does support a "[http://www.jsoftware.com/help/dictionary/dx003.htm Lock Script]" mechanism - to transform a J script so that it's unreadable. However, anyone with access to a machine running the code and ordinary developer tools or who understands the "locking" technique could unlock it.
=={{header|Java}}==
<p>
In order the access a class member of another class which is marked as <code>private</code>, you'll need to use <kbd>reflection</kbd>.<br />
Java offers a collection of <kbd>reflection</kbd>-related utilities within the <code>java.lang.reflect</code> package.
</p>
<p>
In this example I'll use a class with two fields, <code>stringA</code> and <code>stringB</code>.
</p>
<syntaxhighlight lang="java">
class Example {
}
</syntaxhighlight>
<p>
From another class, I'll instantiate <code>Example</code>, and use a <code>Field</code> object to return a specified, declared field.<br />
To do this you call the <code>getDeclaredField</code> on your <code>Class</code> object, supplying the <kbd>name</kbd> of the field.
</p>
<syntaxhighlight lang="java">
Example example = new Example();
Field field = example.getClass().getDeclaredField("stringB");
</syntaxhighlight>
<p>
To allow access to <code>stringB</code> we'll need to use the <code>Field.setAccessible</code> method, and signify <kbd>true</kbd>.<br />
This is essentially what the task is looking for, the ability to override the <kbd>access-modifier</kbd>.
</p>
<syntaxhighlight lang="java">
field.setAccessible(true);
</syntaxhighlight>
<p>
Now, we can access the data from the field by using the <code>Field.get</code> method, specifying the instance as the parameter.
</p>
<syntaxhighlight lang="java">
String stringB = (String) field.get(example);
</syntaxhighlight>
<p>
So, all together our method would contain the following lines.
</p>
<syntaxhighlight lang="java">
Example example = new Example();
Field field = example.getClass().getDeclaredField("stringB");
field.setAccessible(true);
String stringA = example.stringA;
String stringB = (String) field.get(example);
System.out.println(stringA + " " + stringB);
</syntaxhighlight>
<p>
With an output of the following.
</p>
<pre>
rosetta code
</pre>
<p>
If we hadn't used the <code>Field.setAccessible</code> method, we would get an <code>IllegalAccessException</code>.
</p>
<pre>
cannot access a member of class Example with modifiers "private"
</pre>
<p>
Additionally, you can do this with methods via the <code>Method</code> object.<br />
Consider the following class.
</p>
<syntaxhighlight lang="java">
class Example {
String stringA = "rosetta";
private String stringB() {
return "code";
}
}
</syntaxhighlight>
<p>
The approach is the same, except we are using <code>getDeclaredMethod</code>, and instead of <code>get</code> we are using <code>invoke</code>.
</p>
<syntaxhighlight lang="java">
Example example = new Example();
Method method = example.getClass().getDeclaredMethod("stringB");
method.setAccessible(true);
String stringA = example.stringA;
String stringB = (String) method.invoke(example);
System.out.println(stringA + " " + stringB);
</syntaxhighlight>
<pre>
rosetta code
</pre>
Line 670 ⟶ 812:
Julia's object model is one of structs which contain data and methods which are just functions using those structs, with multiple dispatch, rather than object methods, used to distinguish similarly named calls for different object types. Julia does not therefore enforce any private fields in its structures, since, except for constructors, it does not distinguish object methods from other functions. If private fields or methods are actually needed they can be kept from view by placing them inside a module which cannot be directly accessed by user code, such as in a module within a module.
=={{header|Kotlin}}==
For tasks such as this, reflection is your friend:
<
import kotlin.reflect.jvm.isAccessible
Line 688 ⟶ 829:
println("${prop.name} -> ${prop.get(tbb)}")
}
}</
{{out}}
Line 694 ⟶ 835:
secret -> 42
</pre>
=={{header|Logtalk}}==
Logtalk provides a ''context switching call'' control construct that allows a call to be executed as from within an object. It's mainly used for debugging and for writing unit tests. This control construct can be disabled on a global or per object basis to prevent it of being used to break encapsulation.
In the following example, a prototype is used for simplicity.
<
% be sure that context switching calls are allowed
Line 710 ⟶ 850:
bar(3).
:- end_object.</
After compiling and loading the above object, we can use the following query to access the private method:
<
X = 1 ;
X = 2 ;
X = 3
true</
=={{header|Lua}}==
Lua doesn't have a native concept of classes, and the only custom data structure available is the table (in which all fields are always public).
However, it's pretty common for table/object creation functions in object-oriented code to return instances of other functions that uses local variables through lexical scoping, or their closure, which is not accessible to the outside code and could be considered a space with "private" fields.
These can be accessed indirectly through the [https://www.lua.org/manual/5.1/manual.html#5.9 debug library].
<syntaxhighlight lang="lua">local function Counter()
-- These two variables are "private" to this function and can normally
-- only be accessed from within this scope, including by any function
-- created inside here.
local counter = {}
local count = 0
function counter:increment()
-- 'count' is an upvalue here and can thus be accessed through the
-- debug library, as long as we have a reference to this function.
count = count + 1
end
return counter
end
-- Create a counter object and try to access the local 'count' variable.
local counter = Counter()
for i = 1, math.huge do
local name, value = debug.getupvalue(counter.increment, i)
if not name then break end -- No more upvalues.
if name == "count" then
print("Found 'count', which is "..tostring(value))
-- If the 'counter.increment' function didn't access 'count'
-- directly then we would never get here.
break
end
end</syntaxhighlight>
{{out}}
<pre>
Found 'count', which is 0
</pre>
Note that there's an infinite number of other more complex ways for functions to store values in a "private" manner, and the introspection functionality of the debug library can only get you so far.
=={{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.
<syntaxhighlight lang="m2000 interpreter">
Module CheckIt {
Group Alfa {
Line 741 ⟶ 923:
}
CheckIt
</syntaxhighlight>
=={{header|Nim}}==
File oo.nim:
<
a: string
b: string
Line 751 ⟶ 932:
proc createFoo*(a, b, c): Foo =
Foo(a: a, b: b, c: c)</
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:
<
echo x.a # compile time error</
The easiest way to get a debug view of any data:
<syntaxhighlight lang
Output:
<pre>[a = 0x7f6bb87a7050"this a",
Line 763 ⟶ 944:
c = 12]</pre>
More fine-grained:
<
for key, val in fields(toAny(x)):
Line 773 ⟶ 954:
echo " is an integer with value: ", val.getBiggestInt
else:
echo " is an unknown with value: ", val.repr</
Output:
<pre>Key a
Line 781 ⟶ 962:
Key c
is an integer with value: 12</pre>
=={{header|Objective-C}}==
In older versions of the compiler, you can simply access a private field from outside of the class. The compiler will give a warning, but you can ignore it and it will still compile. However, in current compiler versions it is now a hard compile error.
Line 788 ⟶ 968:
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.
<
@interface Example : NSObject {
Line 823 ⟶ 1,003:
}
return 0;
}</
{{out}}
<pre>
Line 833 ⟶ 1,013:
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.
<
@interface Example : NSObject {
Line 882 ⟶ 1,062:
}
return 0;
}</
{{out}}
<pre>
Line 892 ⟶ 1,072:
Finally, you can access the instance variable directly using runtime functions.
<
#import <objc/runtime.h>
Line 929 ⟶ 1,109:
}
return 0;
}</
{{out}}
<pre>
Line 935 ⟶ 1,115:
Hello, I am Edith
</pre>
=={{header|OCaml}}==
Line 946 ⟶ 1,125:
The reader is advised to stop reading here.
<
object
val mutable x = x
Line 978 ⟶ 1,157:
Printf.printf "Broken coord: (%d, %d)\n" x y;
evil_reset p
p#print</
{{out}}
Line 986 ⟶ 1,165:
Broken coord: (-1, -1)
(0, 0)</pre>
=={{header|Oforth}}==
Line 992 ⟶ 1,170:
There is no other way to access attributes values from outside but to call methods on the object.
=={{header|PascalABC.NET}}==
<syntaxhighlight lang="delphi">
uses System.Reflection;
type MyClass = class
private
x: integer := 5;
public
procedure PrintFields := Print(x);
end;
begin
var a := new MyClass;
var fi := a.GetType.GetField('x', BindingFlags.Instance or BindingFlags.NonPublic);
fi.SetValue(a,777);
a.PrintFields;
end.
</syntaxhighlight>
{{out}}
<pre>
777
</pre>
=={{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.
<
sub new {
my $class = shift;
Line 1,009 ⟶ 1,209:
package main;
my $foo = Foo->new();
print "$_\n" for $foo->get_bar(), $foo->{_bar};</
{{out}}
<pre>I am ostensibly private
I am ostensibly private</pre>
=={{header|
{{libheader|Phix/Class}}
Privacy operates by having a context of routine_id(<i>"classname"</i>) in force between the class..end class.<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.
<!--<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;">class</span> <span style="color: #000000;">test</span>
<span style="color: #008080;">private</span> <span style="color: #004080;">string</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"this is a test"</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> <span style="color: #0000FF;">?</span><span style="color: #7060A8;">this</span><span style="color: #0000FF;">.</span><span style="color: #000000;">msg</span> <span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">class</span>
<span style="color: #000000;">test</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new</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: #000080;font-style:italic;">--?t.msg -- illegal
--t.msg = "this is broken" -- illegal</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #008080;">as</span> <span style="color: #000000;">structs</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ctx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"test"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- magic/context
--constant ctx = "test" -- also works
--constant ctx = test -- also works</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">fetch_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: #000000;">ctx</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">" (with some magic)"</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>
<!--</syntaxhighlight>-->
<small>(Obviously you could inline the ctx values rather than create a separate constant.)</small>
{{out}}
<
"this is a test"
"this is a test (with some magic)"
"this breaks privacy"
</pre>
=={{header|PHP}}==
While normally accessing private variables causes fatal errors, it's possible to catch output of some debugging functions and use it. Known functions which can get private variables include: <code>var_dump()</code>, <code>print_r()</code>, <code>var_export()</code> and <code>serialize()</code>. The easiest to use is <code>var_export()</code> because it's both valid PHP code and doesn't recognize private and public variables.
{{works with|PHP|5.1}}
<
class SimpleClass {
private $answer = "hello\"world\nforever :)";
Line 1,085 ⟶ 1,266:
$new_class = eval($class_content);
echo $new_class['answer'];</
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,091 ⟶ 1,272:
{{works with|PHP|4.x}}
{{works with|PHP|5.x}}
<
class SimpleClass {
private $answer = 42;
Line 1,098 ⟶ 1,279:
$class = new SimpleClass;
$classvars = (array)$class;
echo $classvars["\0SimpleClass\0answer"];</
{{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.
<
class fragile {
private $foo = 'bar';
Line 1,113 ⟶ 1,294:
$rp->setValue($fragile, 'haxxorz!');
var_dump($rp->getValue($fragile));
var_dump($fragile);</
{{out}}
<pre>
Line 1,123 ⟶ 1,304:
}
</pre>
=={{header|PicoLisp}}==
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.
<syntaxhighlight lang="picolisp">(class +Example)
# "_name"
(dm T (Name)
(=: "_name" Name) )
(dm string> ()
(pack "Hello, I am " (: "_name")) )
(====) # Close transient scope
(setq Foo (new '(+Example) "Eric"))</syntaxhighlight>
Test:
<syntaxhighlight lang="picolisp">: (string> Foo) # Access via method call
-> "Hello, I am Eric"
: (get Foo '"_name") # Direct access doesn't work
-> NIL
: (get Foo (loc "_name" +Example)) # Locating the transient symbol works
-> "Eric"
: (put Foo (loc "_name" +Example) "Edith")
-> "Edith"
: (string> Foo) # Ditto
-> "Hello, I am Edith"
: (get Foo '"_name")
-> NIL
: (get Foo (loc "_name" +Example))
-> "Edith"</syntaxhighlight>
=={{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:
<
__private = 123
non_private = __private * 2
Line 1,141 ⟶ 1,357:
>>> mine._MyClassName__private
123
>>> </
=={{header|Raku}}==
(formerly Perl 6)
{{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.
<syntaxhighlight lang="raku" line>class Foo {
has $!shyguy = 42;
}
my Foo $foo .= new;
say $foo.^attributes.first('$!shyguy').get_value($foo);</syntaxhighlight>
{{out}}
<pre>42</pre>
=={{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>).
<
class Example
def initialize
Line 1,163 ⟶ 1,390:
p example.instance_variable_set :@private_data, 42 # => 42
p example.instance_variable_get :@private_data # => 42
</syntaxhighlight>
=={{header|Scala}}==
{{libheader|Scala}}<
override def toString = s"Hello, I am $name"
}
Line 1,178 ⟶ 1,404:
field.set(foo, "Edith")
println(foo)
}</
=={{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:
<
has public = "foo"
method init {
Line 1,196 ⟶ 1,421:
# Access private attributes
say obj{:private}; #=> "secret"</
=={{header|Swift}}==
Swift reflection provides a Collection of label-value pairs for struct properties
<
var notSoSecret = "Hello!"
private var secret = 42
Line 1,211 ⟶ 1,435:
print("Value of the secret is \(secret)")
}
</syntaxhighlight>
{{out}}
<pre>Value of the secret is 42</pre>
=={{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:
<
oo::class create Example {
Line 1,227 ⟶ 1,450:
$e print
set [info object namespace $e]::name "Edith"
$e print</
Hello, I am Eric
Hello, I am Edith
=={{header|Visual Basic .NET}}==
{{trans|C#}}
Line 1,237 ⟶ 1,459:
Like the other .NET languages, VB can use Reflection ([https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection Microsoft docs]).
<
' MyClass is a VB keyword.
Line 1,251 ⟶ 1,473:
Console.WriteLine(answer)
End Sub
End Class</
{{out}}
<pre>42</pre>
=={{header|Wren}}==
In Wren all instance and static fields of a class are private and are prefixed by an underscore and a double underscore respectively. There is no way to break the privacy of such fields that I'm aware of (Wren doesn't have reflection). If one wants to provide public access to fields then this is done via getter and/or setter methods.
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.
<syntaxhighlight lang="wren">class Safe {
construct new() { _safe = 42 } // the field _safe is private
safe { _safe } // provides public access to field
doubleSafe { notSoSafe_ } // another public method
notSoSafe_ { _safe * 2 } // intended only for private use but still accesible externally
}
var s = Safe.new()
var a = [s.safe, s.doubleSafe, s.notSoSafe_]
for (e in a) System.print(e)</syntaxhighlight>
{{out}}
<pre>
42
84
84
</pre>
=={{header|zkl}}==
In zkl, privacy is more convention than enforced (unlike const or protected).
<
C.v; C.f; C.D; // all generate NotFoundError exceptions
However:
Line 1,264 ⟶ 1,507:
C.fcns[1]() //-->123
C.classes //-->L(Class(D))
C.vars //-->L(L("",Void)) (name,value) pairs</
In the case of private vars, the name isn't saved.
{{omit from|6502 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|ARM Assembly}}
{{omit from|AWK}}
{{omit from|BASIC}}
{{omit from|BBC BASIC}}
{{omit from|C}}
{{omit from|Déjà Vu}}
{{omit from|GUISS}}
{{omit from|Haskell}}
{{omit from|Icon}}
{{omit from|Locomotive Basic}}
{{omit from|Lotus 123 Macro Scripting}}
{{omit from|Mathematica}}
{{omit from|Rust}}
{{omit from|R}}
{{omit from|SmileBASIC}}
{{omit from|Standard ML|not OO}}
{{omit from|x86 Assembly}}
{{omit from|Z80 Assembly}}
{{omit from|Zig}}
{{omit from|ZX Spectrum Basic}}
{{omit from|Insitux}}
|