/// <summary> /// Try to coerce the values of self and other (using other as the object) then dynamically invoke "<=>". /// </summary> /// <returns> /// 1 if self is greater than other /// 0 if self is equal to other /// -1 if self is less than other /// null otherwise (like if self and other cannot be coerced) /// </returns> /// <remarks> /// This method is used when comparing Numerics. /// If we can't coerce then they are not the same, so return null. /// But if the <=> doesn't exist on the first item in the array returned from coerce then throw missing method error. /// </remarks> public static object CoerceAndCallCompare(RubyContext /*!*/ context, object self, object other) { RubyArray coercedValues; try { // Swap self and other around to do the coercion. coercedValues = RubySites.Coerce(context, other, self); } catch (Exception) { // The coercion failed so return null. return(null); } // This call is outside the try block as we do want problems with this call being raised up. return(LibrarySites.Compare(context, coercedValues[0], coercedValues[1])); }
/// <summary> /// Compare the values of self and other (coerce using other as the object then call the passed in comparison operator). /// </summary> /// <remarks> /// This method is used for <, <=, > and >= operators. If we can't coerce then throw a specific comparison exception. /// </remarks> /// <exception cref="ArgumentException">If self and other cannot be coerced to the same type.</exception> public static bool CoerceAndCallRelationOperator(RubyContext /*!*/ context, object self, object other, DynamicInvocation invoke) { try { // Swap self and other around to do the coercion. RubyArray coercedValues = RubySites.Coerce(context, other, self); return(RubyOps.IsTrue(invoke(context, coercedValues[0], coercedValues[1]))); } catch (MemberAccessException x) { throw RubyExceptions.MakeComparisonError(context, self, other, x); } catch (ArgumentException x) { throw RubyExceptions.MakeComparisonError(context, self, other, x); } catch (NullReferenceException x) { throw RubyExceptions.MakeComparisonError(context, self, other, x); } }
/// <summary> /// Coerce the values of self and other (using other as the object) then call the passed in method. /// </summary> public static object CoerceAndCall(RubyContext /*!*/ context, object self, object other, DynamicInvocation invoke) { RubyArray coercedValues; try { // Swap self and other around to do the coercion. coercedValues = RubySites.Coerce(context, other, self); } catch (MemberAccessException x) { throw RubyExceptions.MakeCoercionError(context, self, other, x); } catch (ArgumentException x) { throw RubyExceptions.MakeCoercionError(context, self, other, x); } // But then swap them back when invoking the operation return(invoke(context, coercedValues[0], coercedValues[1])); }