I made a method like this
class PersonCollection
{
[Contracts.CanReturnNull] //dont know if something like this exists?
IPerson GetPerson(Guid personId)
{
if (this.persons.Contains(personId))
return this.persons[personId];
else
return null;
}
}
Now the calling code needs to handle the null value properly. Is there a way to express a contract for all callers that they need to be able to handle the null value returned by this method?
PersonCollection pc = new PersonCollection();
IPerson p = pc.GetPerson(anyId);
p.Name = "Hugo"; // here I want to have a curly line
What I want is that the p gets marked as potential problematic.
EDIT
I just modified the code and added the calling code and the expcected behaviour. Also I added an attribute that probalbly does not exists on the method GetPerson
Code Contract does not provide such a feature, nor does C#
Code Contracts only requires from the caller to comply to certain constraints at the start of the called method. These are the so-called preconditions.
The postconditions are the responsibility of the callee, and defines what the state of the program will be on exit of the called method.
Design by Contract is a way to define these responsibilities, not to tell callers how they should handle certain conditions caused by the called method.
What you seem to want (after reading the comments) will happen by default:
If you enable Code Contracts in the calling code, the verifier will consider that the return of GetPerson() can be null. So:
IPerson GetPerson(Guid personId)
{
// no pre/post conditions
}
void PrintPerson(IPerson p)
{
Contract.Requires(p != null);
...
}
void Foo()
{
var p = GetPerson(id);
PrintPerson(p); // a warning here: can not verify p != null
}
And, totally irrelevant to the question, this will usually be more efficient if persons is (like) a Dictionary:
IPerson GetPerson(Guid personId)
{
Person p = null;
this.persons.TryGetValue(personId, out p);
return p;
}
Related
The #:op(a.b) feature is described here: https://haxe.io/releases/3.3.0/
I have May<T> abstract which is used for null safety. Here is the simplified version of it:
package;
import haxe.macro.Expr;
abstract May<T>(Null<T>) from(Null<T>){
// convert T, Null<T> or May<T> to May<T>
// accepts Null<T because of 'from(Null<T>)'
// accepts T because Null<T> has 'from(T)'
// we need to accept May<T> to avoid returning May<May<T>> from resolve() if field is already a May
public static inline function from<T>(t:May<T>):May<T> return t;
public inline function exist():Bool return this != null;
public inline function unwrap():T return exist() ? unsafeUnwrap() : throw 'unwrap null';
public inline function unwrapOr(defaultValue:T):T return exist() ? unsafeUnwrap() : defaultValue;
public inline function unsafeUnwrap():T return this;
// return same field from underlying type but as May<FieldType>
#:op(a.b) static macro function resolve<T>(ethis:ExprOf<May<T>>, name:String):Expr {
return macro {
var me = $ethis;
var result = May.from(me.exist() ? me.unsafeUnwrap().$name : null);
result;
}
}
}
Note the resolve() function. It's the new feature that I want to add to my actual May abstract. It allows to safely get fields from May and call unwrap() only once. For example:
may.exist() ? may.unwrap().someField : defaultValue
becomes
may.someField.unwrapOr(defaultValue)
That's very handy and works good. But the completion does not work. It only gives fields from May: unwrap(), exist() etc., but no fields from the underlying class.
I've decided to add #:forward metadata for completion:
#if display #:forward #end
This makes the compiler see all fields during completion. It's better than nothing, but fields have an incorrect type: T instead of May<T>, so I do not get completion for May fields.
I understand why the compiler can't know all possible fields when using #:op(a.b), but maybe there is some more clever trick that will help?
In a Spock Specification any line in expect: or then: block is evaluated and asserted as boolean, unless it has signature with return type void.
I've noticed that there is something odd going on for methods declared as void on any class inheriting from Navigator (for example Page or Module classes).
Let say we have such example:
class NavigationSpec extends GebSpec {
def 'Collections page has a right header'() {
when:
to CollectionsPage
then:
hasHeaderText('Collections')
}
}
The hasHeaderText() method is defined within CollectionsPage class as follows:
class CollectionsPage extends Page {
static url = 'movies/collections'
void hasHeaderText(String expectedText) {
assert true
}
}
On purpose I'm just asserting true over there so it should never fail. Even though it fails with an error:
Condition not satisfied:
hasHeaderText('Collections')
|
null
How and why a void method call result is evaluated as null?
I know how to 'fix it'. It's enough to declare the method return type as boolean and return true. This is ugly though as following all the asserts otherwise unnecessary return true has to be added like:
boolean hasHeaderText(String expectedText) {
assert header.text() == expectedText
return true
}
This causes only noise though. Is there any way to prevent Geb from returning null from void methods?
I'm, of course, aware that this specific case could go like:
boolean hasHeaderText(String expectedText) {
header.text() == expectedText`
}
This doesn't explain the oddity of lost void return type, not to mention we loose meaningful assert failure message with such approach.
It's part of the Groovy language that every method returns a value. This allows any method to be used in expressions or as lambdas.
All methods that are declared void return null.
If you don't explicitly have any return statement, the result of the last expression in your method is returned.
You can look at the bytecode... even if you declare a return type, you don't actually need to return anything as Groovy will, by default, return null:
// returns null
String callMe() { }
static void main(args) {
def x = callMe()
assert x == null
println "OK!"
}
Because Spock will assert anything in the then block which is not a simple assignment, you need to avoid doing anything other than boolean assertions in the then block. Even assigning a variable, though allowed, should be avoided... It's hard to keep tests clean and clear, and by adhering to these guidelines will really work for you in the long run, not against you.
So, the correct way to write the assertion you want is to make your method return a boolean:
boolean hasHeaderText(String expectedText) {
header.text() == expectedText
}
And use it in the then block:
then: 'The header has the expected text #expectedText'
hasHeaderText expectedText
Looks pretty good if you ask me.
EDIT
I've noticed that Groovy/Spock actually will not assert the result of a normal void method even in the then block... What's probably going on here is that you don't have a normal void method, you seem to be calling a dynamic method of CollectionsPage (I guess that's Geb's magic in play), which means that, probably, the Spock AST Transformer does not have the opportunity to check the signature of the method you're calling, so it correctly assumes it must assert the result... at least that's what it looks like.
#Renato is correct in the edited part of his response - your call to a void method gets asserted by Spock because it's a dynamic call and Spock isn't able to figure out that you are calling a void method and eagerly asserts the call. If you changed your code to:
class NavigationSpec extends GebSpec {
def 'Collections page has a right header'() {
when:
CollectionsPage collectionsPage = to CollectionsPage
then:
collectionsPage.hasHeaderText('Collections')
}
}
then it won't get asserted.
In Kotlin, I want to add extension methods to a class, for example to class Entity. But I only want to see these extensions when Entity is within a transaction, otherwise hidden. For example, if I define these classes and extensions:
interface Entity {}
fun Entity.save() {}
fun Entity.delete() {}
class Transaction {
fun start() {}
fun commit() {}
fun rollback() {}
}
I now can accidentally call save() and delete() at any time, but I only want them available after the start() of a transaction and no longer after commit() or rollback()? Currently I can do this, which is wrong:
someEntity.save() // DO NOT WANT TO ALLOW HERE
val tx = Transaction()
tx.start()
someEntity.save() // YES, ALLOW
tx.commit()
someEntity.delete() // DO NOT WANT TO ALLOW HERE
How do I make them appear and disappear in the correct context?
Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the idiomatic answers to commonly asked Kotlin topics are present in SO. Also to clarify some really old answers written for alphas of Kotlin that are not accurate for current-day Kotlin. Other answers are also welcome, there are many styles of how to answer this!
The Basics:
In Kotlin, we tend to use lambdas passed into other classes to give them "scope" or to have behaviour that happens before and after the lambda is executed, including error handling. Therefore you first need to change the code for Transaction to provide scope. Here is a modified Transaction class:
class Transaction(withinTx: Transaction.() -> Unit) {
init {
start()
try {
// now call the user code, scoped to this transaction class
this.withinTx()
commit()
}
catch (ex: Throwable) {
rollback()
throw ex
}
}
private fun Transaction.start() { ... }
fun Entity.save(tx: Transaction) { ... }
fun Entity.delete(tx: Transaction) { ... }
fun Transaction.save(entity: Entity) { entity.save(this) }
fun Transaction.delete(entity: Entity) { entity.delete(this) }
fun Transaction.commit() { ... }
fun Transaction.rollback() { ... }
}
Here we have a transaction that when created, requires a lambda that does the processing within the transaction, if no exception is thrown it auto commits the transaction. (The constructor of the Transaction class is acting like a Higher-Order Function)
We have also moved the extension functions for Entity to be within Transaction so that these extension functions will not be seen nor callable without being in the context of this class. This includes the methods of commit() and rollback() which can only be called now from within the class itself because they are now extension functions scoped within the class.
Since the lambda being received is an extension function to Transaction it operates in the context of that class, and therefore sees the extensions. (see: Function Literals with Receiver)
This old code is now invalid, with the compiler giving us an error:
fun changePerson(person: Person) {
person.name = "Fred"
person.save() // ERROR: unresolved reference: save()
}
And now you would write the code instead to exist within a Transaction block:
fun actsInMovie(actor: Person, film: Movie) {
Transaction { // optional parenthesis omitted
if (actor.winsAwards()) {
film.addActor(actor)
save(film)
} else {
rollback()
}
}
}
The lambda being passed in is inferred to be an extension function on Transaction since it has no formal declaration.
To chain a bunch of these "actions" together within a transaction, just create a series of extension functions that can be used within a transaction, for example:
fun Transaction.actsInMovie(actor: Person, film: Movie) {
film.addActor(actor)
save(film)
}
Create more like this, and then use them in the lambda passed to the Transaction...
Transaction {
actsInMovie(harrison, starWars)
actsInMovie(carrie, starWars)
directsMovie(abrams, starWars)
rateMovie(starWars, 5)
}
Now back to the original question, we have the transaction methods and the entity methods only appearing at the correct moments in time. And as a side effect of using lambdas or anonymous functions is that we end up exploring new ideas about how our code is composed.
See the other answer for the main topic and the basics, here be deeper waters...
Related advanced topics:
We do not solve everything you might run into here. It is easy to make some extension function appear in the context of another class. But it isn't so easy to make this work for two things at the same time. For example, if I wanted the Movie method addActor() to only appear while inside a Transaction block, it is more difficult. The addActor() method cannot have two receivers at the same time. So we either have a method that receives two parameters Transaction.addActorToMovie(actor, movie) or we need another plan.
One way to do this is to use intermediary objects by which we can extend the system. Now, the following example may or may not be sensible, but it shows how to go this extra level of exposing functions only as desired. Here is the code, where we change Transaction to implement an interface Transactable so that we can now delegate to the interface whenever we want.
When we add new functionality we can create new implementations of Transactable that expose these functions and also holds temporary state. Then a simple helper function can make it easy to access these hidden new classes. All additions can be done without modifying the core original classes.
Core classes:
interface Entity {}
interface Transactable {
fun Entity.save(tx: Transactable)
fun Entity.delete(tx: Transactable)
fun Transactable.commit()
fun Transactable.rollback()
fun Transactable.save(entity: Entity) { entity.save(this) }
fun Transactable.delete(entity: Entity) { entity.save(this) }
}
class Transaction(withinTx: Transactable.() -> Unit) : Transactable {
init {
start()
try {
withinTx()
commit()
} catch (ex: Throwable) {
rollback()
throw ex
}
}
private fun start() { ... }
override fun Entity.save(tx: Transactable) { ... }
override fun Entity.delete(tx: Transactable) { ... }
override fun Transactable.commit() { ... }
override fun Transactable.rollback() { ... }
}
class Person : Entity { ... }
class Movie : Entity { ... }
Later, we decide to add:
class MovieTransactions(val movie: Movie,
tx: Transactable,
withTx: MovieTransactions.()->Unit): Transactable by tx {
init {
this.withTx()
}
fun swapActor(originalActor: Person, replacementActor: Person) {
// `this` is the transaction
// `movie` is the movie
movie.removeActor(originalActor)
movie.addActor(replacementActor)
save(movie)
}
// ...and other complex functions
}
fun Transactable.forMovie(movie: Movie, withTx: MovieTransactions.()->Unit) {
MovieTransactions(movie, this, withTx)
}
Now using the new functionality:
fun castChanges(swaps: Pair<Person, Person>, film: Movie) {
Transaction {
forMovie(film) {
swaps.forEach {
// only available here inside forMovie() lambda
swapActor(it.first, it.second)
}
}
}
}
Or this whole thing could just have been a top level extension function on Transactable if you didn't mind it being at the top level, not in a class, and cluttering up the namespace of the package.
For other examples of using intermediary classes, see:
in Klutter TypeSafe config module, an intermediary object is used to store the state of "which property" can be acted upon, so it can be passed around and also changes what other methods are available. config.value("something").asString() (code link)
in Klutter Netflix Graph module, an intermediary object is used to transition to another part of the DSL grammar connect(node).edge(relation).to(otherNode). (code link) The test cases in the same module show more uses including how even operators such as get() and invoke() are available only in context.
I can specify a contract for an automatic property like this (example taken from the CC documentation):
public int MyProperty { get; set ; }
[ContractInvariantMethod]
private void ObjectInvariant () {
Contract. Invariant ( this .MyProperty >= 0 );
...
}
When runtime-checking is turned on, and an attempt is made to assign an invalid value to MyProperty, the setter throws System.Diagnostics.Contracts.__ContractsRuntime+ContractException.
Is there a way to make it throw a specific type of exception - typically, ArgumentNullException, ArgumentOutOfRangeException, or similar, without having to go back and implement the property manually using a backing field and Requires<> ?
No, there isn't.
But as long as your property setter is private, you don't have to worry about that. Any ArgumentException that would be thrown from your setter indicates a bug in the code calling that setter, and should be fixed there. The only code that can call your setter is your own.
If your property setter is protected or public, then you do need to specify which ArgumentException gets thrown for which values.
From the Code Contracts manual:
Object invariants are conditions that should hold true on each instance of a class whenever that object is visible to a client. They express conditions under which the object is in a "good" state.
There's a peculiar couple of sentences in the manual at the top of page 10:
Invariants are conditionally defined on the full-contract symbol [CONTRACT_FULL]. During runtime checking, invariants are checked at the end of each public method. If an invariant mentions a public method in the same class, then the invariant check that would normally happen at the end of that public method is disabled and checked only at the end of the outermost method call to that class. This also happens if the class is re-entered because of a call to a method on another class.
— text in brackets is mine; this is the compile time symbol the manual is referencing which is defined.
Since properties are really just syntactic sugar for T get_MyPropertyName() and void set_MyPropertyName(T), these sentences would seem to apply to properties, too. Looking in the manual, when they show an example of defining object invariants, thy show using private fields in the invariant contract conditions.
Also, invariants don't really communicate to consumers of your library what the pre-conditions or post-conditions for any particular property or method are. Invariants, again, only state to consumers of the library what conditions "hold true on each instance of a class whenever that object is visible to a client." That's all they do. In order to state that if an invalid value will result in throwing an exception, you must specify a pre-condition, which is demonstrated below.
Therefore, it would appear that in order to best achieve what you're looking for, it's as hvd says: it's best to have a private backing field and place the invariant on the backing field. Then you would also provide the contracts on the property getter/setter so that consumers of your library know what the pre-conditions and guaranteed post-conditions (if any) are.
int _myPropertyField = 0;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_myPropertyField >= 0);
}
public int MyProperty
{
get
{
Contract.Ensures(Contract.Result<int>() >= 0);
return _myPropertyField;
}
set
{
Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
_myPropertyField = value;
}
}
Now, there is another way to throw a specific exception using "legacy" code contracts (e.g. if-then-throw contracts). You would use this method if you're trying to retrofit contracts into an existing codebase that was originally written without contracts. Here's how you can do this without using Contract.Requires<TException>(bool cond):
Basically, in Section 5: Usage Guidelines of the manual, you'll be referencing Usage Scenario 3, legacy contract checking (see page 20). This means you need to set the following options in the Code Contracts project properties dialog:
Ensure that the Assembly Mode is set to Custom Parameter Validation.
Use "if-then-throw" guard blocks and perform manual inheritance.private
Ensure Contract.EndContractBlock() follows these guard blocks.
Check Perform Runtime Contract Checking and select the level of checking you want, but only on Debug builds—not on Release builds.
Feel free to use Contract.Requires(bool cond) (non-generic form) on private API methods (e.g. methods not directly callable by a library consumer).
Then, you could write the following code:
private int _myPropertyField = 0;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_myPropertyField >= 0);
}
public int MyProperty
{
get
{
Contract.Ensures(Contract.Result<int>() >= 0);
return _myPropertyField;
}
set
{
if (value < 0)
{
throw new ArgumentOutOfRangeException("value");
}
Contract.EndContractBlock();
_myPropertyField = value;
}
}
Now, you specifically stated that you didn't want to have to go back and create private backing fields for all of your properties. Unfortunately, if this is a public property than can be mutated, then there really is no way to good avoid this. One possible way to avoid this, though, is to make your setter private:
public int MyProperty { get; private set; }
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(MyProperty >= 0);
}
public SetMyProperty(int value)
{
// Using Code Contracts with Release and Debug contract checking semantics:
Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
// Or, using Code Contracts with Debug-only contract checking semantics:
Contract.Requires(value >= 0);
// Using Legacy contracts for release contract checking without throwing
// a ContractException, but still throwing a ContractException for
// debug builds
if (value < 0)
{
throw new ArgumentOutOfRangeException(nameof(value));
}
Contract.EndContractBlock();
MyProperty = value;
}
However, I must admit, I'm not really sure what you're gaining at this point by implementing invariants in this manner. You might as well just bite the bullet and use one of the first two examples I demonstrated above.
Addendum, 2016-02-22
The OP notes in their comment that Section 2.3.1 of the manual mentions that defining object invariants on auto-properties results in the invariant essentially becoming a precondition on the setter and a postcondition on the getter. That's correct. However, the preconditions that are created use the non-generic Contract.Requires(bool condition) form. Why? So that when invariants are used by those who don't want runtime contract checking turned on for their Release builds, they can still use invariants. Therefore, even if you use invariants on properties, if you want a specific exception thrown on contract violations, you must use full properties with backing fields and the generic form of Requires, which also implies that you want to perform runtime contract checking on all builds, including Release builds.
Core Question:
I have a generic interface IValidatingAttribute<T>, which creates the contract bool IsValid(T value); The interface is implemented by a variety of Attributes, which all serve the purpose of determining if the current value of said Field or Property they decorate is valid per the interface spec that I'm dealing with. What I want to do is create a single validation method that will scan every field and property of the given model, and if that field or property has any attributes that implement IValidatingAttribute<T>, it should validate the value against each of those attributes. So, using reflection I have the sets of fields and properties, and within those sets I can get the list of attributes. How can I determine which attributes implement IValidatingAttribute and then call IsValid(T value)?
background:
I am working on a library project that will be used to develop a range of later projects against the interface for a common third party system. (BL Server, for those interested)
BL Server has a wide range of fairly arcane command structures that have varying validation requirements per command and parameter, and then it costs per transaction to call these commands, so one of the library requirements is to easily define the valdiation requirements at the model level to catch invalid commands before they are sent. It is also intended to aid in the development of later projects by allowing developers to catch invalid models without needing to set up the BL server connections.
Current Attempt:
Here's where I've gotten so far (IsValid is an extension method):
public interface IValidatingAttribute<T>
{
bool IsValid(T value);
}
public static bool IsValid<TObject>(this TObject sourceObject) where TObject : class, new()
{
var properties = typeof(TObject).GetProperties();
foreach (var prop in properties)
{
var attributeData = prop.GetCustomAttributesData();
foreach (var attribute in attributeData)
{
var attrType = attribute.AttributeType;
var interfaces = attrType.GetInterfaces().Where(inf => inf.IsGenericType).ToList();
if (interfaces.Any(infc => infc.Equals(typeof(IValidatingAttribute<>))))
{
var value = prop.GetValue(sourceObject);
//At this point, I know that the current attribute implements 'IValidatingAttribute<>', but I don't know what T is in that implementation.
//Also, I don't know what data type 'value' is, as it's currently boxed as an object.
//The underlying type to value will match the expected T in IValidatingAttribute.
//What I need is something like the line below:
if (!(attribute as IValidatingAttribute<T>).IsValid(value as T)) //I know this condition doesn't work, but it's what I'm trying to do.
{
return false;
}
}
}
return true;
}
}
Example usage:
Just to better explain what I am trying to achieve:
public class SomeBLRequestObject
{
/// <summary>
/// Required, only allows exactly 2 alpha characters.
/// </summary>
[MinCharacterCount(2), MaxCharacterCount(2), IsRequired, AllowedCharacterSet(CharSets.Alpha))]
public string StateCode {get; set;}
}
And then, later on in code:
...
var someBLObj = SomeBLRequestObjectFactory.Create();
if(!someBLObj.IsValid())
{
throw new InvalidObjectException("someBLObj is invalid!");
}
Thank you, I'm really looking for a solution to the problem as it stands, but I'm more than willing to listen if somebody has a viable alternative approach.
I'm trying to go generic extension method with this because there are literally hundreds of the BL Server objects, and I'm going with attributes because each of these objects can have upper double digit numbers of properties, and it's going to make things much, much easier if the requirements for each object are backed in and nice and readable for the next developer to have to use this thing.
Edit
Forgot to mention : This Question is the closest I've found, but what I really need are the contents of \\Do Something in TcKs's answer.
Well, after about 6 hours and a goods nights sleep, I realized that I was over-complicating this thing. Solved it with the following (ExtValidationInfo is the class that the below two extensions are in.):
Jon Skeet's answer over here pointed me at a better approach, although it still smells a bit, this one at least works.
public static bool IsValid<TObject>(this TObject sourceObject) where TObject : class, new()
{
var baseValidationMethod = typeof(ExtValidationInfo).GetMethod("ValidateProperty", BindingFlags.Static | BindingFlags.Public);
var properties = TypeDataHandler<TObject>.Properties;
foreach (var prop in properties)
{
var attributes = prop.GetCustomAttributes(typeof(IValidatingAttribute<>)).ToList();
if (!attributes.Any())
{
continue; // No validators, skip.
}
var propType = prop.PropertyType;
var validationMethod = baseValidationMethod.MakeGenericMethod(propType);
var propIsValid = validationMethod.Invoke(null, prop.GetValue(sourceObject), attributes);
if(!propIsValid)
{
return false;
}
}
return true;
}
public static bool ValidateProperty<TPropType>(TPropType value, List<IValidatingAttribute<TPropType>> validators)
{
foreach (var validator in validators)
{
if (!validator.IsValid(value))
{
return false;
}
}
return true;
}