Browse Source

completed specifications of Lambda and Reflect

Simon Krajewski 12 years ago
parent
commit
0e34e84ca9

+ 10 - 1
std/Lambda.hx

@@ -165,7 +165,16 @@ class Lambda {
 	}
 
 	/**
-		Functional 'fold' using an [Iterable]
+		Functional fold on Iterable [it], using function [f] with start argument
+		[first].
+		
+		If [it] has no elements, the result is [first].
+		
+		Otherwise the first element of [it] is passed to [f] alongside [first].
+		The result of that call is then passed to [f] with the next element of
+		[it], and so on until [it] has no more elements.
+		
+		If [it] or [f] are null, the result is unspecified.
 	**/
 	public static function fold<A,B>( it : Iterable<A>, f : A -> B -> B, first : B ) : B {
 		for( x in it )

+ 38 - 3
std/Reflect.hx

@@ -103,22 +103,57 @@ extern class Reflect {
 	public static function isFunction( f : Dynamic ) : Bool;
 
 	/**
-		Generic comparison function, does not work for methods, see [compareMethods]
+		Compares [a] and [b].
+		
+		If [a] is less than [b], the result is -1. If [b] is less than [a], the
+		result is 1. If [a] and [b] are equal, the result is 0.
+		
+		This function is only defined if [a] and [b] are of the same type.
+		
+		If that type is a function, the result is unspecified and
+		[Type.compareMethods()] should be used instead.
+		
+		For all other types, the result is 0 if [a] and [b] are equal. If they
+		are not equal, the result depends on the type and is -1 if:
+			Numeric types: a is less than b
+			String: a is lexicographically less than b
+			Other: unspecified
+		
+		If [a] and [b] are null, the result is 0. If only one of them is null,
+		the result is unspecified.
 	**/
 	public static function compare<T>( a : T, b : T ) : Int;
 
 	/**
-		Compare two methods closures. Returns true if it's the same method of the same instance.
+		Compares the functions [f1] and [f2].
+		
+		If [f1] or [f2] are not functions, the result is unspecified.
+		
+		Otherwise the result is true if [f1] and the [f2] are physically equal,
+		false otherwise.
 	**/
 	public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool;
 
 	/**
-		Tells if a value is an object or not.
+		Tells if [v] is an object.
+		
+		The result is true if [v] is one of the following:
+			- class instance
+			- structure
+			- Class<T>
+			- Enum<T>
+			
+		Otherwise, including if [v] is null, the result is false.
 	**/
 	public static function isObject( v : Dynamic ) : Bool;
 
 	/**
 		Tells if [v] is an enum value.
+		
+		The result is true if [v] is of type EnumValue, i.e. an enum
+		constructor.
+		
+		Otherwise, including if [v] is null, the result is false.
 	**/
 	public static function isEnumValue( v : Dynamic ) : Bool;
 	

+ 2 - 0
tests/unit/TestSpecification.hx

@@ -53,6 +53,8 @@ private class EmptyClass {
 	public function new() { }
 }
 
+@:keep private class ReallyEmptyClass { }
+
 private class ClassWithToString {
 	public function new() { }
 	public function toString() return "ClassWithToString.toString()";

+ 6 - 0
tests/unit/unitstd/Lambda.unit.hx

@@ -85,6 +85,12 @@ Lambda.array(Lambda.filter([],function(i) return false)) == [];
 Lambda.array(Lambda.filter([],function(i) return true)) == [];
 Lambda.array(Lambda.filter([],null)) == [];
 
+
+// fold
+Lambda.fold(["b","c","d"],function(s,acc) return s + acc,"a") == "dcba";
+Lambda.fold([],function(s:String,acc) return s + acc,"a") == "a";
+Lambda.fold([],function(s:String,acc) return s + acc,null) == null;
+
 // count
 Lambda.count([1,2,3]) == 3;
 Lambda.count([1,2,3], function(x) return false) == 0;

+ 70 - 1
tests/unit/unitstd/Reflect.unit.hx

@@ -1,4 +1,4 @@
-#if false
+#if !php
 // hasField
 var x = { a: 1, b: null };
 Reflect.hasField(x, "a") == true;
@@ -80,4 +80,73 @@ var y = Reflect.copy(x);
 Reflect.field(y, "a") == 2;
 Reflect.field(y, "b") == null;
 Reflect.field(y, "c") == null;
+
+//compare
+Reflect.compare(1,2) == -1;
+Reflect.compare(2,1) == 1;
+Reflect.compare(1,1) == 0;
+Reflect.compare("abcd","e") == -1;
+Reflect.compare("abcd","abcd") == 0;
+Reflect.compare("e","abcd") == 1;
+Reflect.compare(null,null) == 0;
+Reflect.compare("abcd",null) != 0;
+Reflect.compare(null, "abcd") != 0;
+
+// compareMethods
+var x = function(t) return 1;
+var y = function(t) return -1;
+var z = function(t) return 1;
+Reflect.compareMethods(x,y) == false;
+Reflect.compareMethods(x,z) == false;
+Reflect.compareMethods(y,z) == false;
+Reflect.compareMethods(x,x) == true;
+Reflect.compareMethods(y,y) == true;
+Reflect.compareMethods(z,z) == true;
+//Reflect.compareMethods(x,null) == false;
+//Reflect.compareMethods(null,x) == false;
+//Reflect.compareMethods(null,null) == false; // varies
+
+// isObject
+Reflect.isObject({}) == true;
+Reflect.isObject({v:"f"}) == true;
+Reflect.isObject(new C()) == true;
+Reflect.isObject(new C2()) == true;
+Reflect.isObject(new CChild()) == true;
+Reflect.isObject(new CDyn()) == true;
+Reflect.isObject(new EmptyClass()) == true;
+Reflect.isObject(Type.createEmptyInstance(ReallyEmptyClass)) == true;
+Reflect.isObject("foo") == true;
+Reflect.isObject(E) == true;
+Reflect.isObject(C) == true;
+
+Reflect.isObject(1) == false;
+Reflect.isObject(1.1) == false;
+Reflect.isObject(true) == false;
+Reflect.isObject(EA) == false;
+Reflect.isObject(EVMB()) == false;
+Reflect.isObject(null) == false;
+var x:C = null;
+Reflect.isObject(x) == false;
+
+// isEnumValue
+Reflect.isEnumValue(EA) == true;
+Reflect.isEnumValue(EVMB()) == true;
+
+Reflect.isEnumValue({}) == false;
+Reflect.isEnumValue({v:"f"}) == false;
+Reflect.isEnumValue(new C()) == false;
+Reflect.isEnumValue(new C2()) == false;
+Reflect.isEnumValue(new CChild()) == false;
+Reflect.isEnumValue(new CDyn()) == false;
+Reflect.isEnumValue(new EmptyClass()) == false;
+Reflect.isEnumValue(Type.createEmptyInstance(ReallyEmptyClass)) == false;
+Reflect.isEnumValue("foo") == false;
+Reflect.isEnumValue(E) == false;
+Reflect.isEnumValue(C) == false;
+Reflect.isEnumValue(1) == false;
+Reflect.isEnumValue(1.1) == false;
+Reflect.isEnumValue(true) == false;
+Reflect.isEnumValue(null) == false;
+var x:C = null;
+Reflect.isEnumValue(x) == false;
 #end