Posts Tagged ‘Injectionless’

Injectionless DCI in Ruby part III

Posted: February 11, 2013 in DCI
Tags: , ,

A few weeks back while debating Marvin on the object-composition group we talked about the meaning of ‘this’ in a role method. Today while working on Moby I realized how important it is that self/this point to the role itself inside a role method. It hasn’t bugged me while using Marvin but when using a dynamic language like Ruby where there’s no compiler that will ask “Did you really mean this? because I don’t know what you are trying to do” it’s paramount that the code shows the intention clearly and since DCI is all about clarity this should be reflected in other languages as well. It is already reflected in Marvin, and has been ever since that discussion.

Advertisement

Injectionless DCI in Ruby part II

Posted: January 30, 2013 in DCI
Tags: , , ,

My latest post was on Injectionless DCI in Ruby was based on an approach using method_missing. I’ve since then diverted from that path. I started bench marking the code against simple ordinary method invocation and I wasn’t satisfied with the result. I could get the invocation of a role method down to a factor of 2.5 compared to a regular method call but could get any further improvement with my code using using method_missing so I needed a different approach which ended in a little piece of code I’ve called Moby it’s heavily inspired by how Marvin works and was surprisingly easy to write in Ruby.

All it really does is transformation of method invocation on roles. If there’s a suiting tole method it will call the role method if not it will send the message to self acting as a Ruby script would otherwise normally have done.

Since this happens at interpretation time there’s no performance hit when actually executing the method invocation. There will be an overload in the start up but once that’s paid there’s no penalty only the DCI goodies such as expressive code, separation between what the system is and what it does.

Being a first release and still having to convert more of the “canonical DCI examples” to use this piece of code I’m sure I’ll have to fix some bugs and make improvements to the code. The next example is the Dijkstra – Manhattan where I’m rewriting Jim Copliens #extend based version found on our fullOO site

When the Dijkstra example is done I will have to learn yet another new skill. How to construct a RubyGem until then the code can be found at http://github/runefs/Moby

Injectionless DCI in Ruby

Posted: January 24, 2013 in DCI
Tags: , ,

The last few years I’ve been rather active in the DCI community but never really blogged much about it. This post is not going to be my first post on the main DCI concepts either. I’ve been fairly active on the mailing list object-composition, on stackoverflow.com and not least developing the Marvin compiler. One should think with all that activity I’d have enough information to a series of blog post and potentially an entire book and one would probably be right. However this time around I’ll will stick to describing the use of a Ruby tool I’ve recently created.

The first step to creating this tools was learning Ruby altogether. Until recently I’d only read Ruby but never actually coded anything in Ruby nor read a text on the subject and I couldn’t find a better “hello world” that trying to replicate functionality I’d already coded in a different language.

Inspired by a discussion on SO, where you could be led to believe that DCI in Ruby requires using #extend and that it will always be slow I decided to see how many of the tricks used in the Marvin compiler to change C# into Marvin I could replicate in Ruby. From a functional point of view I’m satisfied with the result

The canonical DCI example (MoneyTransfer) looks like this

class MoneyTransfer < Context
#Create a role called source with two role methods 'withdraw' and 'log'
role :source do
    role_method :withdraw do |amount|
           source.movement(amount)
           source.log "withdrawal #{amount}"
    end
    role_method :log do |message|
      p "role #{message}"
    end
  end


#Create a role called source with two role methods 'deposit'

role :destination do
 role_method :deposit do |amount|
 destination.movement(amount)
 destination.log "deposit #{amount}"
 end
end

interaction :transfer do |amount|
 source.withdraw -amount
 destination.deposit amount
end

def initialize(s,d)
 self.source = s
 self.destination = d
end
end

There's three methods in play here to actually generate the code
  • role -> defines a role, the accessor to the current RolePlayer is defined as private
  • role_method -> defines a role method, though it’s defined as a block, that block is never really executed. Instead it’s transformed into an instance method of the context class
  • interaction -> defines a public instance method. The only “magic” here has to do with bookkeeping in relation to the context stack

There’s absolutely no use of #extend. However there’s is some dynamic changes to classes but these are only performed the first time an object of a given type is playing any role and in the odd case where a role method and an instance method clashes then this is handled on a class level as well.


Being a Ruby novice there might be some subtleties I’ve missed or even big no-nos 🙂 however for the MoneyTransfer I’ve verified that


  • An instance method is chosen even if the object is playing two roles in the same context and the ‘other’ role defines a method with the same name (in the example above log is both a role method for source and on the account object I used for testing)
  • A role method is chosen over an instance method if the current role defines a method that clashes with an instance method
  • The role behavior doesn’t leak. I.e. the object looses the capabilities as soon as it stops playing the role (or when accessed outside the role context (pun not intended)
At present the code can be found as a gist