Class Module
In: lib/mues/utils.rb  (CVS)
Parent: Object

A couple of syntactic sugar aliases for the Module class.

Module::implements
An alias for include. This allows syntax of the form:
  class MyClass < MUES::Object; implements MUES::Debuggable, AbstracClass
    ...
  end
Module::implements?
An alias for Module#<, which allows one to ask SomeClass.implements?( Debuggable ).

Methods

External Aliases

include -> implements
  Syntactic sugar for mixin/interface modules. (Borrowed from Hipster‘s component "conceptual script" - www.xs4all.nl/~hipster/)
include? -> implements?

Public Instance methods

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.

[Source]

/* 
 * 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.

[Source]

/* 
 * 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;
}

[Validate]