a minor AHA!

53 views
Skip to first unread message

Trygve Reenskaug

unread,
May 21, 2013, 4:33:41 AM5/21/13
to DCI-object-composition
I was working with the MoveShape example (BB8bMoveShape). It's about a drawing where the user can move a shape and see that the attached connectors move with it. There are three roles: MovingShape, Connectors, and Delta.
(The demo example, BB8MoveShape, has a single Connector for simplicity. BB8bMoveShape is more general and has multiple connectors to a shape.)

The Connectors role is played by a collection object that contains the connectors attached to the MovingShape. The minor aha! was that the Connectors role was like any other role and could have roleMethods.

MovingShape::move
    self move: Delta.
    Connectors shapeHasMoved.


Connectors::shapeHasMoved 
    self do: [:connector | connector pointAt: MovingShape put: MovingShape center].


The Connectors role is played by an  OrderedCollection and is an untouchable library class. But the code is safe since the roleMethod cannot touch the class. AHA!, a RoleMethod can be attached to an instance of a library class

So far, so good and I went through all my examples to see if their code could be simplified. Greed is a dice game. The program simulates playing the game with different players; each player has his own strategy for the game. The Roles are: GameMaster, Players, CurrentPlayer, Cup, Dice,  I look at the code bottom-up:
  
The CurrentPlayer RoleMethod is
CurrentPlayer::yourTurn
    "code for this particular player rolling the dice etc."

The Players role is a collection role containing a number of Player objects.   I would like to say
    self do: [:player | player yourTurn].
But yourTurn is a roleMethod so this message is not understood by the player object. I therefore added a new Collection subclass with a method for enumerating over a collection of objects that successively play a given role.

The code now reads:
Players::playOneRound
    self with: #CurrentPlayer do: [:player | CurrentPlayer yourTurn].


The collection itself and its free enumeration variable are both played by roles.
This entails that the mapping of an individual role is changed dynamically. I'm not supposed to like that, since all roles should be mapped together in a single operation to ensure consistency. I find comfort in the thought that this happens in a support class and not in user code.

Not elegant and the syntax should be improved. But it works. Take it as a proof of concept.

--Trygve

rune funch

unread,
May 21, 2013, 9:41:16 AM5/21/13
to object-co...@googlegroups.com
I'm using a similar trick in maroon and Jim is in his Ruby dijkstra example. I had the exact same objection that you do, that not all roles are mapped together and would like to improve the syntax. I do have an idea of what the syntax should be for maroon but haven't gotten that far yet.

the same can easily be accomplished by a nested context but the instantiation of a new object might be a problem if you have a lot of element for that reason I'd like to avoid nested context in maroon. I would however love if the syntax made it clear that the role was only available in a given scope.

Currently this is how you'd do


role :method do
   def is_private
   end
end

def my_interaction
      my_collection.select do |e|
         bind :e => :method
         method.is_private?
      end   
end

notice the bind in the line in bold. THat's telling marron that in this block the object identified by e is playing the role method

the change I want to make is something like

def my_interaction
      my_collection.select do |e|
         bind :e => role :method do
                                 def is_private
                                 end
                            end
         method.is_private?
      end   
end

That is defining the role as part of the block and potentially (As above) as part of the bind syntax (The call to bind and the argument(s) are all transformed before the actual execution of the context/block)

-Rune



2013/5/21 Trygve Reenskaug <try...@ifi.uio.no>

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages