Break OO privacy: Difference between revisions

Add Ecstasy example
m (Automated syntax highlighting fixup (second round - minor fixes))
(Add Ecstasy example)
Line 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>&nbsp;public&nbsp;</tt></span>, <span style="background-color: #e5e4e2"><tt>&nbsp;protected&nbsp;</tt></span>, and <span style="background-color: #e5e4e2"><tt>&nbsp;private&nbsp;</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.println($"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.println($"after: {expo}");
}
}
</syntaxhighlight>
 
Output:
<syntaxhighlight>
before: pub="public", pro="protected", pri="private"
after: pub="this was public!!!", pro="this was protected!!!", pri="this was private!!!"
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
{{trans|C#}}
162

edits