On Wed, Jun 10, 2015 at 11:13 PM, Martin Dias <tinchodias@gmail.com> wrote:
Hi everybody,
I'm writing you to discuss about a new feature for Pharo. I would like to know your opinions and ideas. Thanks in advance.
My point is that there are operations like "MC version load", "change set file in", "RB refactoring execution", or "class copy" that produce code change announcements (e.g. ClassAdded or MethodAdded), but subscribers can't know that. I mean, a subscriber that listens a ClassAdded can't know if it is product of a "high-level" operation, or if it was manually performed by the user in the Nautilus browser.
I think Pharo should provide a way to detect this information, because it can be very useful. For example, I can tell you about a tool I work on: Epicea. Epicea logs code changes while developer works (like traditionally done with the .changes file), and the user can browse, undo and redo changes. Now, imagine that your vm crashed and then you want to recover "lost" changes... you don't want to see hundreds of changes produced by Monticello when loading packages: in this case, such changes are noise and make you waste time when selecting what to redo. In Epicea package I have a workaround for detecting some "high-level" operations, but Epicea would need support from Pharo for a nice implementation.
Brainstorming on implementations.
I think announcements are a good mechanism to implement this feature. A simple approach is to provide begin and end announcements (e.g. MCVersionLoadBegin and MCVersionLoadEnd). Then, somebody that subscribes to such announcements can have a stack or state machine to know the context where each code change announcement is produced. It would look like:
MCVersionLoader >> load ... SystemAnnouncer uniqueInstance announce: (MCVersionLoadBegin versionName: ...). [ ... produce code changes ... ] ensure: [ SystemAnnouncer uniqueInstance announce: (MCVersionLoadEnd versionName: ...) ].
which may be re-written with a convenience method as: ... SystemAnnouncer uniqueInstance announceBefore: (MCVersionLoadBegin versionName: ...) announceAfter: (MCVersionLoadEnd versionName: ...) do: [ ... produce code changes ... ]
but, going one step further, we could reify the concept of announcement begin and end like: ... announcement := (MCVersionLoad versionName: ...). SystemAnnouncer uniqueInstance announceBefore: (AnnouncementBegin of: announcement) announceAfter: (AnnouncementEnd of: announcement) do: [ ... produce code changes ... ]
which could be re-written as: ... SystemAnnouncer uniqueInstance announceBeforeAndAfter: (MCVersionLoad versionName: ...) do: [ ... produce code changes ... ]
I think any approach can work, but I'd love to have some feedback.
Kind regards, MartÃn
The first thought that occurs to me is whether Announcements can be hierarchical. So the "low-level" announcements have a "high-level" announcement as their parent. Then the "recover changes" interface shows only the high-level changes at the first tree level, but you can still drill down to disable individual "low-level" changes. Sorry, in trying to think of an opinion for begin/end pattern I come up blank. Not enough experience with it. cheers -ben