Giter Club home page Giter Club logo

Comments (8)

aranega avatar aranega commented on August 29, 2024 1

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.

aranega avatar aranega commented on August 29, 2024 1

@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.

willcrick avatar willcrick commented on August 29, 2024

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.

willcrick avatar willcrick commented on August 29, 2024

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.

willcrick avatar willcrick commented on August 29, 2024

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.

aranega avatar aranega commented on August 29, 2024

@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.

willcrick avatar willcrick commented on August 29, 2024

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.

willcrick avatar willcrick commented on August 29, 2024

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 photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.