// dynamic dispatch to "const_missing" if not found public object ResolveConstant(bool autoload, string /*!*/ name) { object result; if (TryResolveConstant(autoload, name, out result)) { return(result); } RubyUtils.CheckConstantName(name); return(RubySites.ModuleConstMissing(RubyContext, GetInnerMostModule(), name)); }
public static MutableString Inspect(RubyContext /*!*/ context, YamlStream /*!*/ self) { MutableString result = MutableString.CreateMutable("#<YAML::Stream:"); RubyUtils.AppendFormatHexObjectId(result, RubyUtils.GetObjectId(context, self)) .Append(" @documents=") .Append(RubySites.Inspect(context, self.Documents)) .Append(", options=") .Append(RubySites.Inspect(context, self.Options)) .Append('>'); return(result); }
public static object Tagurize(RubyContext context, RubyModule self, object arg) { if (arg == null) { return(null); } if (RubySites.RespondTo(context, arg, "to_str")) { return(MutableString.Create("tag:yaml.org,2002:").Append(Protocols.ConvertToString(context, arg))); } return(arg); }
/// <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])); }
public static MutableString /*!*/ ObjectToMutableString(RubyContext /*!*/ context, object obj) { using (IDisposable handle = RubyUtils.InfiniteInspectTracker.TrackObject(obj)) { if (handle == null) { return(MutableString.Create("...")); } MutableString str = MutableString.CreateMutable(); str.Append("#<"); str.Append(context.GetClassOf(obj).Name); // Ruby prints 2*object_id for objects str.Append(':'); AppendFormatHexObjectId(str, GetObjectId(context, obj)); // display instance variables RubyInstanceData data = context.TryGetInstanceData(obj); if (data != null) { var vars = data.GetInstanceVariablePairs(); bool first = true; foreach (KeyValuePair <string, object> var in vars) { if (first) { str.Append(" "); first = false; } else { str.Append(", "); } str.Append(var.Key); str.Append("="); str.Append(RubySites.Inspect(context, var.Value)); } } str.Append(">"); return(str); } }
private static string /*!*/ FormatMethodMissingMessage(RubyContext /*!*/ context, object self, string /*!*/ name, string /*!*/ message) { Assert.NotNull(name); string strObject; if (self == null) { strObject = "nil:NilClass"; } else { strObject = RubySites.ToS(context, self).ConvertToString(); if (!strObject.StartsWith("#")) { strObject += ":" + RubyUtils.GetClassName(context, self); } } return(String.Format(message, name, strObject)); }
/// <summary> /// Try to cast the object to an Integer using to_int /// Returns null if the object doesn't implement to_int /// Can return either Bignum or Fixnum /// </summary> public static bool AsInteger(RubyContext /*!*/ context, object obj, out int fixnum, out BigInteger bignum) { // Don't call to_int on types derived from Integer if (AsPrimitiveInteger(obj, out fixnum, out bignum)) { return(true); } if (RubySites.RespondTo(context, obj, "to_int")) { object result = _ToInt.Target(_ToInt, context, obj); if (AsPrimitiveInteger(result, out fixnum, out bignum)) { return(true); } throw RubyExceptions.InvalidValueForType(context, result, "Integer"); } return(false); }
/// <summary> /// Standard way to convert to a Ruby String, using to_str /// /// Checks if it's already a string, and if so returns it. /// Then calls to_str if it exists, otherwise returns null /// </summary> public static MutableString AsString(RubyContext /*!*/ context, object obj) { MutableString str = obj as MutableString; if (str != null) { return(str); } if (RubySites.RespondTo(context, obj, "to_str")) { str = _ToStr.Target(_ToStr, context, obj) as MutableString; if (str != null) { return(str); } throw RubyExceptions.MethodShouldReturnType(context, obj, "to_str", "String"); } return(null); }
public static Node /*!*/ ToYaml(double self, [NotNull] RubyRepresenter /*!*/ rep) { MutableString str = RubySites.ToS(rep.Context, self); if (str != null) { if (str.Equals("Infinity")) { str = MutableString.Create(".Inf"); } else if (str.Equals("-Infinity")) { str = MutableString.Create("-.Inf"); } else if (str.Equals("NaN")) { str = MutableString.Create(".NaN"); } } return(rep.Scalar(self, str)); }
public static object GetConstant(RubyScope /*!*/ scope, RubyModule /*!*/ owner, string /*!*/ name, bool lookupObject) { Assert.NotNull(scope, owner, name); object result; if (owner.TryResolveConstant(scope.GlobalScope, name, out result)) { return(result); } RubyClass objectClass = owner.Context.ObjectClass; if (owner != objectClass && lookupObject && objectClass.TryResolveConstant(scope.GlobalScope, name, out result)) { return(result); } CheckConstantName(name); return(RubySites.ModuleConstMissing(scope.RubyContext, owner, name)); }
/// <summary> /// Try to convert obj to an Array using #to_ary /// 1. If obj is an Array (or a subtype), returns it /// 2. Calls to_ary if it exists, possibly throwing if to_ary doesn't return an Array /// 3. else returns null /// </summary> public static IList AsArray(RubyContext /*!*/ context, object obj) { // Don't call to_a on types derived from Array IList ary = obj as IList; if (ary != null) { return(ary); } if (RubySites.RespondTo(context, obj, "to_ary")) { object result = _ToAry.Target(_ToAry, context, obj); ary = result as IList; if (ary != null) { return(ary); } throw RubyExceptions.MethodShouldReturnType(context, obj, "to_ary", "Array"); } return(null); }
protected CallSite <Func <CallSite, RubyContext, object, Proc, object> > /*!*/ GetSite(string /*!*/ name) { CallSite <Func <CallSite, RubyContext, object, Proc, object> > result; lock (_siteCache) { if (!_siteCache.TryGetValue(name, out result)) { result = CallSite <Func <CallSite, RubyContext, object, Proc, object> > .Create(RubySites.InstanceCallAction(name, RubyCallSignature.WithBlock(0))); _siteCache[name] = result; } } return(result); }
/// <summary> /// Protocol for determining value equality in Ruby (uses IsTrue protocol on result of == call) /// </summary> public static bool IsEqual(RubyContext /*!*/ context, object lhs, object rhs) { return(IsTrue(RubySites.Equal(context, lhs, rhs))); }
/// <summary> /// Casts to symbol. Note that this doesn't actually use to_sym -- it uses to_str. /// That's just how Ruby does it. /// /// Another fun detail: you can pass Fixnums as Symbols. If you pass a Fixnum that /// doesn't map to a Symbol (i.e. Fixnum#to_sym returns nil), you get an ArgumentError /// instead of a TypeError. At least it produces a warning about using Fixnums as Symbols /// </summary> public static string /*!*/ CastToSymbol(RubyContext /*!*/ context, object obj) { if (obj is SymbolId) { return(SymbolTable.IdToString((SymbolId)obj)); } if (obj is int) { return(RubyOps.ConvertFixnumToSymbol(context, (int)obj)); } else { MutableString str = AsString(context, obj); if (str != null) { return(RubyOps.ConvertMutableStringToSymbol(str)); } } throw RubyExceptions.CreateTypeError(String.Format("{0} is not a symbol", RubySites.Inspect(context, obj))); }
public static Exception /*!*/ InvalidValueForType(RubyContext /*!*/ context, object obj, string type) { return(CreateArgumentError(String.Format("invalid value for {0}: {1}", type, RubySites.Inspect(context, obj).ConvertToString()))); }
public static Node ToYaml(object self, [NotNull] RubyRepresenter /*!*/ rep) { return(rep.Scalar(self, RubySites.ToS(rep.Context, self))); }
public static MutableString InflateStream(RubyClass /*!*/ self, MutableString zstring) { object obj = RubySites.Allocate(self); return(InflateSite.Target(InflateSite, self.Context, obj, zstring)); }
public static void ConvertToIntegerRange(RubyContext /*!*/ context, Range /*!*/ range, out int begin, out int end, out bool excludeEnd) { begin = Protocols.CastToFixnum(context, RubySites.RangeBegin(context, range)); end = Protocols.CastToFixnum(context, RubySites.RangeEnd(context, range)); excludeEnd = RubySites.RangeExcludeEnd(context, range); }
internal RubyPropertyDescriptor(string name, object testObject, Type componentType) : base(name, null) { _name = name; _componentType = componentType; _getterSite = CallSite <Func <CallSite, RubyContext, object, object> > .Create(RubySites.InstanceCallAction(_name)); _setterSite = CallSite <Func <CallSite, RubyContext, object, object, object> > .Create(RubySites.InstanceCallAction(_name + "=")); try { _propertyType = GetValue(testObject).GetType(); } catch (Exception) { _propertyType = typeof(object); } }