| Class | Module |
| In: |
lib/mues/utils.rb
(CVS)
|
| Parent: | Object |
A couple of syntactic sugar aliases for the Module class.
class MyClass < MUES::Object; implements MUES::Debuggable, AbstracClass
...
end
| include | -> | implements |
| Syntactic sugar for mixin/interface modules. (Borrowed from Hipster‘s component "conceptual script" - www.xs4all.nl/~hipster/) | ||
| include? | -> | implements? |
abstract( VALUE self, int argc, VALUE *argv ) — Declare a method as abstract or unimplemented in the current namespace:
abstract :myVirtualMethod, :myOtherVirtualMethod
Calling a method declared in this fashion will result in a VirtualMethodError being raised.
/*
* abstract( VALUE self, int argc, VALUE *argv )
* --
* Declare a method as abstract or unimplemented in the current namespace:
* abstract :myVirtualMethod, :myOtherVirtualMethod
* Calling a method declared in this fashion will result in a
* VirtualMethodError being raised.
*
*/
VALUE
mues_abstract( argc, argv, self )
VALUE self, *argv;
int argc;
{
int i;
VALUE absClass;
// Check to make sure the abstract method is being declared in an abstract
// class
absClass = rb_const_get(mues_mMUES, rb_intern( "AbstractClass" ));
DebugMsg(( "Checking <%s> class to make sure it implements AbstractClass",
rb_class2name(self) ));
if( rb_mod_include_p(self, absClass) == Qfalse )
rb_raise( rb_eScriptError, "Cannot declare abstract methods for a concrete class" );
DebugMsg(( "Adding %d virtual methods.", argc ));
// Iterate over each symbol, adding an abstract method for each one.
for(i = 0; i < argc; i++) {
DebugMsg(( "...adding abstract method '%s'", rb_id2name(SYM2ID( argv[i] )) ));
rb_define_method( self, rb_id2name(SYM2ID( argv[i] )), mues_dummy_method, -1 );
}
return Qtrue;
}
abstract_arity( VALUE self, int argc, VALUE *argv ) — Declare a method as abstract or unimplemented in the current namespace, with checks for a given arity:
abstract_arity :myVirtualMethod, 5
Calling a method declared in this fashion that has not been overridden will result in a MUES::VirtualMethodError being raised. Overriding the abstract method with a method which doesn‘t have the specified arity or greater will cause a MUES::VirtualMethodError to be raised when the overriding class‘s initializer is called.
/*
* abstract_arity( VALUE self, int argc, VALUE *argv )
* --
* Declare a method as abstract or unimplemented in the current namespace, with
* checks for a given arity:
* abstract_arity :myVirtualMethod, 5
* Calling a method declared in this fashion that has not been overridden will
* result in a MUES::VirtualMethodError being raised. Overriding the abstract
* method with a method which doesn't have the specified arity or greater will
* cause a MUES::VirtualMethodError to be raised when the overriding class's
* initializer is called.
*/
VALUE
mues_abstract_arity(argc, argv, self)
VALUE self, *argv;
int argc;
{
VALUE symbol, arity, virtualMethodTable;
if ( argc != 2 )
rb_raise( rb_eArgError, "wrong number of arguments (%d for 2)", argc );
symbol = *(argv);
arity = *(argv+1);
mues_abstract( 1, (VALUE *)&symbol, self );
// If the class already has a virtual method table, fetch it; otherwise make a
// new one.
if ( RTEST(rb_ivar_defined( self, rb_intern("@virtualMethods") )) )
virtualMethodTable = rb_iv_get( self, "@virtualMethods" );
else
virtualMethodTable = rb_hash_new();
// Now set the tuple for this method and set it back in the class
rb_hash_aset( virtualMethodTable, symbol, arity );
DebugMsg(( "Virtual method '%s' required arity set to %d in virtual methods table of %s class",
rb_id2name(SYM2ID( symbol )),
FIX2INT(arity),
rb_class2name(self) ));
rb_iv_set( self, "@virtualMethods", virtualMethodTable );
if ( !RTEST(rb_ivar_defined( self, rb_intern("@virtualMethods") )) )
rb_raise( rb_eScriptError, "Failed to set @virtualMethods on %s class.", rb_class2name(self) );
return Qtrue;
}