QVT copy operation on models - eclipse

I need to make changes in an instance of a model (preserving the original) using QVT. I thought in using the copy() operation which is defined in the QVT Documentation (As one of Orerations on models), but I don't understand how to use it, I have tried to execute the next code and look if the Out instance is copied from the In instance, but didn't have any luck:
modeltype MMNotation "strict"
uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation';
transformation QVTONotationTransformation(in SourceNotation: MMNotation,
out TargetNotation: MMNotation);
main() {
TargetNotation := SourceNotation.copy();
}

Looks like a bug in total model assignment. Please raise a Bugzilla. I think you should have got a warning that you cannot assign to a created model.
Try using deepclone of the root element instead, or assignment of the contents of the copy.
Regards
Ed Willink

Related

How to get an OrderedSet of OccurrenceSpecifications from a Lifeline in QVTo?

From the diagram on page 570 of the UML spec I concluded that a Lifeline should have the events property, holding an OrderedSet(OcurrenceSpecification). Unfortunately it is not there, at least in the QVTo implementation that I use.
All I have is the coveredBy property, serving me with an (unordered) Set(InteractionFragment). Since my transformation relies on the correct order of MessageOcurrenceSpecification I somehow need to implement myself what I expected to be implemented by the missing events property.
This is what I have so far:
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.coveredBy->selectByKind(OccurrenceSpecification)->sortedBy(true);
}
Obviously sortedBy(true) does not get me far, but I don't know any further. Who can help?
All I could find so far were other people struggling with the same issue years ago, but no solution:
https://www.eclipse.org/forums/index.php/m/1049555/
https://www.eclipse.org/forums/index.php/m/1050025/
https://www.eclipse.org/forums/index.php/m/1095764/
Based on the answer by Vincent combined with input from a colleague of mine I came up with the following solution for QVTo:
-- -----------------------------------------------------------------------------
-- Polyfill for the missing Lifeline::events property
query Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.fragment
->selectByKind(OccurrenceSpecification)
->select(os: OccurrenceSpecification | os.covered->includes(self))
->asOrderedSet();
}
I don't know if it is possible, using directly coveredBy to get an ordered collection. As coveredBy is unordered, if you access it directly by the feature, you will have an unpredictible order and if you try to access it using the eGet(...) stuff, the same result will occur.
However, if I understood correctly, there is a "trick" that could work.
It relies on the assumption that each OccurrenceSpecification instance you need is held by the same Interaction that contains the Lifeline and uses the way EMF stores contained elements. Actually, each contained element is always kind of 'ordered' relatively to its parent (and for each collection so EMF can find elements back when XMI references are expressed using the element position in collections). So, the idea would be to access all the elements contained by the Interaction that owns the lifeline and filter the ones that are contained in coveredBy.
Expression with Acceleo
This is easy to write in MTL/Acceleo. In know you don't use it, but it illustrates what the expression does:
# In Acceleo:
# 'self' is the lifeline instance
self.interaction.eAllContents(OccurrenceSpecification)->select(e | self.coveredBy->includes(e))->asOrderedSet()
with self.interaction we retrieve the Interaction, then we get all the contained elements with eAllContents(...) and we filter the ones that are in the self.coveredBy collection.
But it is way less intuitive in QVT as eAllContents(...) does not exist. Instead you have to gain access to eContents() which is defined on EObject and returns an EList which is transtyped to a Sequence (in QVT,eAllContents() returns a ETreeIterator which is not transtyped by the QVT engine).
So, how to gain access to eContents() in the helper? There is two solutions:
Solution 1: Using the emf.tools library
The emf.tools library give you the ability to use asEObject() which casts your object in a pure EObject and give you more methods to access to (as eClass() for example...etc).
import emf.tools; -- we import the EMF tools library
modeltype UML ...; -- all your metamodel imports and stuffs
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.asEObject().eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Solution 2: Using oclAstype(...)
If for some reason emf.tools cannot be accessed, you can still cast to an EObject using oclAsType(...).
modeltype UML ...; -- all your metamodel imports and stuffs
modeltype ECORE "strict" uses ecore('http://www.eclipse.org/emf/2002/Ecore'); -- you also register the Ecore metamodel
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.oclAsType(EObject).eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Limitation
Ok, let's be honest here, this solution seems to work on the quick tests I performed, but I'm not a 100% sure that you will have all the elements you want as this code relies on the strong assumption that every OccurrenceSpecification you need are in the same Interaction as the Liteline instance. If you are sure that all the coveredBy elements you need are in the Interaction (I think they should be), then, that's not the sexiest solution, but it should do the work.
EDIT>
The solution proposed by hielsnoppe is more eleguant than the one I presented here and should be prefered.
You are correct. The Lifeline::events property is clearly shown on the diagram and appears in derived models such as UML.merged.uml.
Unfortunately Eclipse QVTo uses the Ecore projection of the UML metamodel to UML.ecore where unnavigable opposites are pruned. (A recent UML2Ecore enhancement allows the name to be persisted as an EAnnotation.) However once the true property name "events" has been pruned the implicit property name "OccurrenceSpecification" should work.
All associations are navigable in both directions in OCL, so this loss is a bug. (The new Pivot-based Eclipse OCL goes back to the primary UML model in order to avoid UML2Ecore losses. Once Eclipse QVTo migrates to the Pivot OCL you should see the behavior you expected.)

MATLAB: overriding table() methods

SETUP Win7 64b, R2015b, 16 GB of RAM, CPU i7-2700
The table() is a fundamental Matlab class which is also sealed, hence I cannot subclass it.
I want to fix some methods of this class and add new ones.
For instance, table.disp() is fundamentally broken, e.g. try NOT disp(table(rand(1e7,1))), or forget the ; in the command window. The variable takes only 76 MB in RAM but the display is unbuffered and it will stall your system!
Can I override methods like table.disp() without writing into matlabroot\toolbox\matlab\datatypes\#table?
Can I extend the table class with a new method under C:\MATLAB\#table\ismatrixlike.m? Why do I get
ismatrixlike(table)
Undefined function 'ismatrixlike' for input arguments of type 'table'.
Obviously, I did
addpath C:\MATLAB\
rehash toolboxcache
I also tried clear all.
The path has (alphabetic) precedence over matlabroot, but is missing a table.m class definition. If I add the native class defition to C:\MATLAB\#table, then I can run my new method (after a clear all). However:
>> methods(table)
Methods for class table:
classVarNames ismatrixlike table varfun
convertColumn renameVarNames unstack
only lists the methods in the new \#table folder, even though (some of) the old methods still work, e.g.
size(table)
This partly solves the problem, since now, the native \#table\private folder is not accessible anymore and therefore many native methods are broken!
Why am I doing this? Because I do not want to wait another 2 years before the table() is fixed. I already lost entire days because I simply forgot a ; in the command window and I cannot force a restart on my pc if it is running multiday simulations, but I have to wait for the disk-swap to end :(.
APPENDIX
More context about disp(table(rand(1e7,1))). This is what happens when I hit it (and luckily I am fast enough to CTRL-C out of it):
The culprit is line 172 of table.disp() which converts the numeric array into a cellstring (with the padding too!):
[cells, err, isLeft] = sprintfc(f, x, b);
After experimenting with several alternatives, I adopted the solution that intereferes the least with Matlab's native #table implementation and it's easily removed if things go awry.
The solution:
copy the whole #table folder, i.e. fullfile(matlabroot,'toolbox','matlab','datatypes','#table'), into a destination where you have write permissions.
I picked the destination to be fullfile(matlabroot,'toolbox','local','myfiles') since I do not have to bother with OS cross-compatibility, i.e. matlabroot takes care of that for me.
paste into the destination your #table folder with the new, overloaded and overriding methods (partially overwriting the copied original files)
add the destination to the matlab path, before the original #table, e.g. addpath your_destination -begin
Effects, pros and cons:
The native #table class/methods are now shadowed, try e.g. which table -all. However, this effect is quite clear, easily detectable and easily removed (delete destintation and remove path);
No weird conflicts between native #table (now shadowed) and new #table;
All methods, new and old, are visible, try methods(table);
Private table methods are accessible...
... but you are forced to use them.
Exposing the new methods (user-implemented) to the private ones requires more maintenance and direct handling of version conflicts in the table implementations.
You need write permissions on some eligible destination.
For those interested about the details, you can look into, https://github.com/okomarov/tableutils. Specifically the install_tableutils (the readme might not be updated).
The following works for me:
Define a modified disp function, say disp_modified.m, as follows, and put it in your path:
function disp_modified(t)
if istable(t)
%// Do whatever you want to display tables
builtin('disp', '''disp'' function intercepted!')
else
%// For non-tables, call `disp` normally
builtin('disp', t)
end
Define disp as a function handle to the modifed function (you can do that in startup.m to always have it by default):
disp = #disp_modified;
After this, in the command window I get
>> disp(1:5)
1 2 3 4 5
>> disp({1 2 3 'bb'})
[1] [2] [3] 'bb'
>> disp(table(rand(1e3,1)))
'disp' function intercepted!
Depending on the usage of the new class perhaps you could follow a cleaner approach. The proposed approach described in your post has the drawback that perhaps code used in your updated environment would not be easily portable to a new environment, or a program executed in your environment may demonstrate different behavior in a different environment.
Some questions you could consider (and perhaps clarify) would be: How do you intend to use the new class? Do you want to replace all the existing table uses? Do you want to be able to use it instead of a table class argument? Or do you want to alter the table so that each usage of the original table class in your environment uses the new class.
If you just need a new improved table for your usage, you could consider encapsulating the original table class in a new class. E.g MyTable, delegate all the methods you do not need to the original table methods, replace the methods you would like to improve or add new ones.
Update: Just saw the complete solution in Github and understood what you intended to do. Nice work. I will leave the post in case anyone finds it useful.

MATLAB doesn't show help for user-created class private methods and properties

This is the problem:
Create a class and set the access to be private for some of the properties or methods.
Use the doc command for the created class. This will auto-generate documentation from your comments and show it in the built-in help browser.
doc classname
The problem is that documentation for the private properties and methods is not shown in the help browser. Is there any way to overcome this problem?
So I spent like 10 minutes using the debugger, jumping from one function to the next, tracing the execution path of a simple doc MyClass call.
Eventually it lead me to the following file:
fullfile(toolboxdir('matlab'),'helptools','+helpUtils','isAccessible.m')
This function is called during the process of generating documentation for a class to determine if the class elements (including methods, properties, and events) are publicly accessible and non-hidden. This information is used later on to "cull" the elements.
So if you are willing to modify MATLAB's internal functions, and you want the docs to always show all methods and properties regardless of their scope, just rewrite the function to say:
function b = isAccessible(classElement, elementKeyword)
b = true;
return
% ... some more code we'll never reach!
end
Of course, don't forget to make a backup of the file in case you changed your mind later :)
(on recent Windows, you'll need to perform this step with administrative privileges)
As a test, take the sample class defined in this page and run doc someClass. The result:
This behaviour is by design - the auto-generated documentation is intended for users of the class, who would only be able to access the public properties and methods.
There's no way that I'm aware of to change this behaviour.
You could try:
Use an alternative system of auto-generating documentation such as this from the MATLAB Central File Exchange (which I believe will document all properties, not just public).
Implement your own doc command. Your doc command should accept exactly the same inputs as the built-in doc command, detect if its inputs correspond to your class/methods/properties etc, and if so display their documentation, otherwise pass its inputs straight through to the built-in doc. Make sure your command is ahead of the built-in on the path.

Are there special rules to follow when putting splitting coffeescript classes into separate files?

I'm trying to change some otherwise working code by pulling all the classes into separate files. This works for most classes, except for the part where it reads class window.Timeline. The error message reads ReferenceError: window is not defined
Any suggestions?
It sounds like your file containing that class isn't getting loaded into the window context. Is it possible that it got loaded in the context of another class? Could you post some cod examples in a jsFiddle?
The pattern that I usually follow when exporting coffeescript symbols to the parent context is
exports = exports ? this
class MyClass
someField: false
exports.MyClass = MyClass
If you are using a modern browser and know how to access the debugging console, you could put
console.log this
At the end of the file that is throwing the reference error. This will allow you to have a look to see what the this context is, which may help you troubleshoot.

lua - capturing variable assignments

Ruby has this very interesting functionality in which when you create a class with 'Class.new' and assign it to a constant (uppercase), the language "magically" sets up the name of the class so it matches the constant.
# This is ruby code
MyRubyClass = Class.new(SuperClass)
puts MyRubyClass.name # "MyRubyClass"
It seems ruby "captures" the assignment and inserts sets the name on the anonymous class.
I'd like to know if there's a way to do something similar in Lua.
I've implemented my own class system, but for it to work I've got to specify the same name twice:
-- This is Lua code
MyLuaClass = class('MyLuaClass', SuperClass)
print(MyLuaClass.name) -- MyLuaClass
I'd like to get rid of that 'MyLuaClass' string. Is there any way to do this in Lua?
When assigning to global variables you can set a __newindex metamethod for the table of globals to catch assignments of class variables and do whatever is needed.
You can eliminate one of the mentions of MyLuaClass...
> function class(name,superclass) _G[name] = {superclass=superclass} end
> class('MyLuaClass',33)
> =MyLuaClass
table: 0x10010b900
> =MyLuaClass.superclass
33
>
Not really. Lua is not an object-orientated language. It can behave like one sometimes. But far from every time. Classes are not special values in Lua. A table has the value you put in it, no more. The best you can do is manually set the key in _G from the class function and eliminate having to take the return value.
I guess that if it REALLY, REALLY bothers you, you could use debug.traceback(), get a stack trace, find the calling file, and parse it to find the variable name. Then set that. But that's more than a little overkill.
With respect at least to Lua 5.2: You can capture assignments to A) the global table of a Lua State, as mentioned in a previous reply, and also B) to any other Lua Object whose __index and __newindex metamethods have been substituted (by replacing the metatable), this I can confirm as I'm currently using both these techniques to hook and redirect assignments made by Lua scripts to external C/C++ resource management.
There is a gotcha with regards to reading them back though, the trick is to NOT let the values be set in a Lua State.
As soon as they exist there, your hooks will fail to be called, so if you want to go down this path, you need to capture ALL get/set attempts, and NEVER store the values in a Lua State.