Comments (8)
Actually, two functions already exist in catsoo to replace a subchar: replace
and replaceAll
. Their signature are defined as follow:
replace : (s:String x oldstr:String x newstr:String) -> String
replaceAll : (s:String x regex:String x subs:String) -> String
They are implemented exactly as in Java, replace
works on 'strict' subchains while replaceAll
work with regular expressions. I will try asap to give in the documentation a quick overview of the existing builtin functions.
Anyway, your code seems fine to me, I will add your function to my tests cases and see what happens.
In your case, the code would become:
var strings:=['string1','myUml','testUmlxxx','Id'];
strings := strings->replace('Uml', 'UML'); // see below for explanations
Regarding the collection update, actually, basic operations on collections cannot modify collections, only some function does. When you use the iteration operator ->
, a new collection is created instead of modification of the existing one, so:
var a := [1, 2, 3];
log(a->_apply(self + 1));
actually creates a new collection with [2, 3, 4]
. In order to get the result, you have to do:
a := a->_apply(self + 1);
If you use _iter
instead of _apply
however, the returned collection would be a copy of the input one. Actually, _iter
always return the element it has as first parameter, while _apply
always return the result of the statement it has as second parameter. While handling basic elements, _iter
is not very useful, but when handling elements, it becomes more interesting, for example:
var new_names := __ROOT objects[Class]->select(eĀ | e.name startwith('myclass'))->_iter(self.name := self.name replace('Uml', 'UML')->_apply(self.name);
This loooon statement would get all the Class
from the root, filter the class which have a name that starts with 'myclass', modify the name of these classes then on the collection of classes 'collect' all the names. By the way, please not that in that case, the expression could have been reduced to:
var new_names := __ROOT objects[Class]->select(eĀ | e.name startwith('myclass'))->_apply(self.name := self.name replace('Uml', 'UML');
as the :=
operator always returns the assigned value.
from catsoolang.
@willcrick That's a really good news and very interesting to know! I would never have expected safari to run better than chrome for this kind of operations. I will still work on your issues as the 'recursive' error looks like a default in the interpreter. Also, I've perhaps a solution in mind that could speed up everything.
Thanks a lot for your patience Will!
from catsoolang.
Excellent info @aranega thank you!
I looked for string replacement functions in the catsoolang doc page and also in the eclipse Acceleo/OCL documentation and could not find anything, so i thought it would be fun to write them myself. But very happy to use something already defined!
Is there also a method for determining if a substring is contained within a given string? I also wrote a small method for this which works ok, but sometimes also gives the
Unexpected error while executing your code: (RangError) : Maximum call stack size exceeded
error. Its defined below:
def hasCharsInString(chars: String, in: String) : Boolean
{
for(i: range( in length()-chars length() ) ){
log('substring='+ in substring( i, (i+chars length()) ));
if( in substring( i, (i+chars length()) )=chars ){
return true;
}
}
}
What i am trying to achieve is being able to traverse through all of the objects in my model, and replace any package, class or property that contains 'Uml' and replace it with 'UML'. I will change my current method to use some concepts that you have highlighted above and get back to you as to if it works and my final solution.
P.s. If there is another place i should be asking questions about Catsoolang, then let me know. The genmymodel.com support site didnt seem to have anything but feature requests, so i thought here was the best place.
from catsoolang.
OK, i have it working:
var chars:='Uml';var replaceChars:='UML';var result:=model objects()->select(e|(e isKindOf(Class) or e isKindOf(Property) or e isKindOf(Package) or e isTypeOf(Interface)))->_apply(self.name:=self.name replace(chars,replaceChars));
I didnt need to determine if a substring is contained in a string, and in fact my method above caused one of my problems, as its returned the string, not the object that owned the string, which then got built into a collection of strings which were disconnected from the model objects. So my result strings were correct, but the model objects did not get updated.
What i dont still understand is the difference between _iter and _apply and how to ensure that they actually update model objects. One statement above is a little confusing to me:
Actually, _iter always return the element it has as first parameter, while _apply always return the result of the statement it has as second parameter.
When you say returned as first or second parameter, what does that mean? The operations only return a single object?
While handling basic elements, _iter is not very useful, but when handling elements, it becomes more interesting
Whats the difference between a basic element and an element in this case? Is it the difference between a String and an Model Object? If so can you explain how they are handled differently?
Thanks so much for your help! It has made my renaming task in my very large model so much easier!!!
from catsoolang.
So it works in my test project š but not in my main project š
Quite often the chrome tab just crashes, so its hard to repro.
Using __ROOT
rather than model
seems to work better (dont get as many errors). But it never runs to completion and never changes all of my model text. I will continue to work on it tomorrow...
from catsoolang.
@willcrick I see, I've reproduced the 'long-running script' symptom, it seems that on large models, the pre-treatments that are done on the model in order to tmp isolate it from the model is too heavy for large models... I will work on that and find a solution to speed up everything. Unfortunately, with old chrome version, hitting "wait" few times was enough to let the script finish, but I didn't succeed this time (last chrome version). I'm not sure that there is a direct link, but it I will keep this in mind.
In the same time, you can use the tree in GenMyModel, as you can filter element by substrings. Then, with the 'bring to location' tool, you can rename them by hand (I know, this is not ideal, but at the moment, this is the quickest solution I can think of).
Is there also a method for determining if a substring is contained within a given string?
Yes, there is the matches
function that works with regular expressions. You can use, for example:
'abcUmlPost' matches('.*Uml.*')
What i dont still understand is the difference between _iter and _apply and how to ensure that the actually update model objects. One statement above is a little confusing to me
Actually, _iter
and _apply
are almost empty shells, they are mainly used to 'chain' a parameter as return value.
_iter
and _apply
takes two parameters a
and b
which can be Any
type and return either a
or b
:
cl> log(_iter(1, 2));
1
cl> log(_apply(1, 2));
2
As in castoolang, the first parameter of a function can be 'detached' from the parameters, _iter(1, 2)
is equivalent to 1 _iter(2)
. When you deal with model elements, it means that you can get as output either the element on which the statement has been applied or the result of the application:
cl> var classes := __ROOT modelElements()[Class]; // modelElements is like objects, but does not return graphical elements
cl> classes->_iter(self.name := self.name + 'X');
// returns the collection of classes
while:
cl> classes->_apply(self.name := self.name + 'X');
// returns the collection of names
In these two cases: _iter
and _apply
would modify the model elements because of self.name := self.name + 'X'
. This feature is mainly used for chaining many requests.
Using __ROOT rather than model seems to work better (dont get as many errors).
Actually, model
depends on your model, has many root model element are named model
and that you can navigate through elements by name, the single model
statement represents the navigation by name from the model root to the element named model
. __ROOT
on the other hand is a special variable that always points to the model root, so it's better to use __ROOT
š .
P.s. If there is another place i should be asking questions about Catsoolang, then let me know. The
genmymodel.com support site didnt seem to have anything but feature requests, so i thought here was
the best place.
Here is totally fine š don't worry about it.
I sorry that there is such an issue with large models, I will work on this asap to provide you a better solution.
from catsoolang.
Great info @aranega, thanks.
I just tried doing it on each individual type (Classes first) using matches
to see if that helps with performance. Unfortunately, i still get Aw, Snap! I might try in a few other browsers actually.
Otherwise i will have to do it by hand. Problem is, i have hundreds of classes, methods, properties and parameters to change (Json to JSON, Html to HTML and a few other acronyms to change the case of).
I now understand the difference between _iter
and _apply
.
from catsoolang.
OK, got it working with Safari on my mac:
I split it into separate commands for each element type, so for Parameters it looks like this:
var chars:='uri';var replaceChars:='URI';var result:=__ROOT modelElements()[Parameter]->select(e | e.name matches('.*'+chars+'.*'))->_iter(self.name := self.name replace(chars,replaceChars));
Seems to be much faster in Safari, and is better than doing it manually!
from catsoolang.
Related Issues (1)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ššš
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from catsoolang.