-
Notifications
You must be signed in to change notification settings - Fork 343
Modifying the sources
Before fixing a bug, please make sure that there is a failing RubySpec for the defect. The spec should test for all the corner cases like:
- nil arguments
- arguments that can be converted via
to_<type>methods like to_s - if blocks can be passed even to a method which does not use the block
- missing block for a method which requires a block
- if the return value of the block is returned back
- Use .NET Framework conventions for all identifiers. There is no specific guideline for naming private fields in this document; we prefix field names with underscores (e.g.
private string _fooBar). If you’re not sure about some convention try to find out in the rest of the IronRuby code or ask in the list.
- Use
/*!*/for method parameters and instance fields that should never be null. Spec# annotations.
- Do not use public fields (Base::algorithm, buffer). Use properties if it is necessary to expose the field or private/internal visibility otherwise. Also use readonly if the field is not mutated after the object is constructed.
- Add a regular C# class or method, and mark it with
[RubyClass("ClassName")]or[RubyMethod("method_name")]. - Compile (alias is
brbd) - Run
geninitto generate C# initialization code into c:\path\to\Merlin\Main\Languages\Ruby\Libraries.LCA_RESTRICTED\Initializers.Generated.cs. - Compile again
Note that if you change the signature of an existing method already marked with RubyMethodAttribute, compilation will fail as Initializers.Generated.cs will have initialization code for the old signature. In this case, you can edit the initialization code by hand to match the new signature. However, an easier solution is to delete all the contents of Initializers.Generated.cs, compile, run geninit, and compile again. This requires an extra compilation step, but avoids the manual updating of the initialization code.
- 0 or more Storage
- 0 or 1 of either of
RubyContext/*!*/ contextorRubyClass/*!*/ self - 1 of
object selffor instance methods - 0 or 1 of BlockParam
- Remaining user-visible parameters
- Parameters should be as strongly-typed as possible. For example, use “MutableString arg” if the method takes a String.
- Do not do the type check imperatively in the code with a cast, even for error handling. The IronRuby engine should throw the right error message if the user passes in an incorrect argument type.
- Using multiple C# overloads – If a Ruby method accepts either String of Fixnum, use two C# overloads with MutableString and System.Int32. The IronRuby engine will make this visible as a single Ruby method
- Automatic conversion – the IronRuby engine will automatically call to_s on the object if the parmeter is declared as “[DefaultProtocol]MutableString arg”.
- [NotNull] – The IronRuby engine will throw the appropriate error message if the user passes in nil, but the Ruby method does not allow nil.
[RubyClass("Fixnum", Extends = typeof(int), Inherits = typeof(Integer))]
public static class FixnumOps {
...
[RubyMethod("<")]
public static bool LessThan(
BinaryOpStorage/*!*/ coercionStorage,
BinaryOpStorage/*!*/ comparisonStorage,
RubyContext/*!*/ context,
object self,
object other) {
return Protocols.CoerceAndRelate(coercionStorage, comparisonStorage, "<", context, self, other);
}
...
}
Here’s a video to see the workflow of a simple bug fix
The following commands will build and run all the tests that are required to pass.
brbd irtests