Ruby mixin

Like many other programmers I wish I had started learning Ruby when it was created, all the more so for the demand for broad programming skills now. I started using NetBeans 6.1 which made JRuby programming easier. I started to look at some example code written in other languages and write equivalent Ruby code. If you have good programming experience ( Updated : Hope it is not the Kruger-Dunning effect :-)then you can start with fairly complex code when learning a new language.

The example is JavaScript event code that can be mixed-in with other code. Actually I came across many powerful features of JavaScript when I programmed using RhinoScript recently.

I hope to update the code but as of now I have the skeleton below. I wouldn’t be able to explain everything because this is my first serious piece of Ruby code. I will try to use this “mixin” code along with other code.

    Updated : Used a module. Exploring how to write proper test code.

event_mixin_module.rb

module EventMixinModule
  $listeners

  EventManager   = { "notify" => proc {
                                    puts "notify"
                                    if ( nil == defined?($listeners) )
                                      puts "No listeners registered"
                                    end
                                    puts $listeners
                                  },
                     "listen" => proc {
                                    |listen|
                                    puts "listen"
                                    $listeners = listen || [];
                                 }
                  }
  puts EventManager["listen"].call( "listener" )
  #puts EventManager["notify"].call
    
end

domain_object.rb


require "event_mixin_module"

class DomainObject
  include EventMixinModule
  def initialize
    puts "DomainObject"
  end
  
  def setvalue
  puts "setvalue"
  EventManager["notify"].call
  end

end

domain_object_test.rb


require "domain_object"

class DomainObjectTest
  def initialize
    
  end
  domainobject = DomainObject.new
  domainobject.setvalue
  
end

Groovy Mixins

Groovy has limited support for features like those introduced by AOP. I am just wondering when we will see AOP languages rather than extensions to other languages. Was AOP really designed to only complement OO ? Is it really possible to write a AOP language from scratch ? The following is Groovy code that uses inter-type declarations. You can type this in the Groovy console to create a Mixin.

public class Test{

@Property name;
}

import java.beans.*;

public class InterTypeCategoryListener implements PropertyChangeListener{

public void propertyChange(PropertyChangeEvent e){
println "Property [" + e.getPropertyName() + "] changed from " +
e.getOldValue() + " to " + e.getNewValue();
}

}

import java.beans.*;

public class InterTypeCategory{

static PropertyChangeSupport support = new PropertyChangeSupport(this);

public static void addPropertyChangeListener(
Test bean,
PropertyChangeListener listener){
support.addPropertyChangeListener(listener);
}

public static void addPropertyChangeListener(
Test bean,
String propertyName,
PropertyChangeListener listener){
support.addPropertyChangeListener( propertyName,
listener);
}

public static void removePropertyChangeListener(
Test bean,
String propertyName,
PropertyChangeListener listener) {
support.removePropertyChangeListener( propertyName,
listener);
}

public static void removePropertyChangeListener(
Test bean,
PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
public static void hasListeners(
Test bean,
String propertyName) {
support.hasListeners(propertyName);
}

public static void firePropertyChange(
Test bean,
Test b1,
String property,
String oldval,
String newval) {
System.out.println( "The old value is [" + oldval + "]");
System.out.println( "The new value is [" + newval + "]");
support.firePropertyChange( property,
( oldval == null ) ? oldval : new String(oldval),
new String(newval));
}

static String test = "Inter-Type Declaration";

static String getSupport( Test bean ) {
return support;
}

static String setName( Test bean, String newval ) {
println "Firing Property Change event"
String oldValue = bean.name
bean.name = newval
firePropertyChange( bean, bean, "name", oldValue, bean.name );
}

}

use( InterTypeCategory.class ){
Test test = new Test()
test.addPropertyChangeListener( new InterTypeCategoryListener() )
test.setName( "Test" );
println "Value [" + test.name + "]"
test.setName( "Test1" );
println "Value [" + test.name + "]"
}