Reflective Equality is a set of global functions that allows two Swift ‘Any’ instances to be compared by value.
Values are compared by recursively traversing their properties and subproperties, as well as those of their parents (and parents’ parents, etc.), combining the reflection affordances of Swift.Mirror, Swift.String(describing:), and the Objective C runtime. If all property values match, they are considered equal, even if the class instances are not identical (i.e., !==).
Guidance
There is no way to prove that this works on a general basis, and there are inevitably edge cases where a spurious result will be generated. The output is therefore only guaranteed to be correct against the kinds of test cases used to drive the package’s development.
If you’re not sure if you need this, you almost certainly don’t! It is best used for very particular cases when you can be sure it will do the job for you, and that the job is one that actually should be done in the first place. Though it is still under active development (and suggestions are welcome), consider it more of a curiosity than anything else!
Usage
The framework offers three main public functions:
public func haveSameValue(_ args: [Any]) -> Bool
public func haveSameValue(_ lhs: Any, _ rhs: Any) -> Bool
public func deepDescription(_ instance: Any) -> String
Clearly the above examples are equatable, so the use of String instances is purely for example’s sake - clearly an extra package isn’t needed to do this.
Slightly more interestingly, a comparison of Equatable conforming types that can’t be made reliably with ==:
Swift has a lovely way of telling you that all kinds of things are an NSObject. Which they sort of are. And aren’t. And maybe. But really, if I ask it if struct Swift.String { } is an NSObject, in a pure Swift context I’d prefer it just said no. Which ReflectiveEquality does.
Reflective Equality also has a completely experimental set of functions for probing ObjC properties and ivars:
extension NSObject {
public var propertiesAndIvars: [String: Any]
public var ivars: [String: Any]
public var properties: [String: Any]
public var propertyAndIvarValues: [Any]
public var propertyValues: [Any]
public var ivarValues: [Any]
}
properties are fine, but ivars have a habit of crashing horribly with EXC_BAD_ACCESS when you try to probe them from Swift. So, have fun blowing things up!
Reflective Equality
Reflective Equality is a set of global functions that allows two Swift ‘Any’ instances to be compared by value.
Values are compared by recursively traversing their properties and subproperties, as well as those of their parents (and parents’ parents, etc.), combining the reflection affordances of
Swift.Mirror
,Swift.String(describing:)
, and the Objective C runtime. If all property values match, they are considered equal, even if the class instances are not identical (i.e.,!==
).Guidance
There is no way to prove that this works on a general basis, and there are inevitably edge cases where a spurious result will be generated. The output is therefore only guaranteed to be correct against the kinds of test cases used to drive the package’s development.
If you’re not sure if you need this, you almost certainly don’t! It is best used for very particular cases when you can be sure it will do the job for you, and that the job is one that actually should be done in the first place. Though it is still under active development (and suggestions are welcome), consider it more of a curiosity than anything else!
Usage
The framework offers three main public functions:
These can be used as follows:
Clearly the above examples are equatable, so the use of
String
instances is purely for example’s sake - clearly an extra package isn’t needed to do this.Slightly more interestingly, a comparison of
Equatable
conforming types that can’t be made reliably with==
:This case applies to various NS… classes. Maybe you’d like to see if two
NSFont
instances are the same font? Or stuff like that.Here’s an unusual use case for
deepDescription
:Swift has a lovely way of telling you that all kinds of things are an
NSObject
. Which they sort of are. And aren’t. And maybe. But really, if I ask it ifstruct Swift.String { }
is anNSObject
, in a pure Swift context I’d prefer it just said no. Which ReflectiveEquality does.Reflective Equality also has a completely experimental set of functions for probing ObjC properties and ivars:
properties
are fine, butivars
have a habit of crashing horribly withEXC_BAD_ACCESS
when you try to probe them from Swift. So, have fun blowing things up!