How to change all variable names in a Matlab function?

I would like to have a method for duplicating a function and at the same time rename all variables in the file so that they have a specific prefix, for example:
function c = main(m)
a = m*2
b = m*3
c = a+b+m;
should be duplicated and the prefix 'main_' should be added. The new function becomes:
function main_c = main(main_m)
main_a = main_m*2
main_b = main_m*3
main_c = main_a+main_b+main_m;
It can be done in the Matlab editor ( see here ) but I would like to do it via code.
Thanks for any inputs :)

5 commentaires

What is the aim of this? A use-case description would be helpful.
I will try to explain :)
The reason is that we have a number of functions that contain an optimization model for a given unit. Hereby, each unit can be optimized individually by running the function
y1 = unit1(x1,z)
y2 = unit1(x2,z)
The functions depend both on local variables (x1 and x2, respectively) but also on global variables (z). I would like to merge the two functions into a "master" function
y = units(x1, x2, z)
because this function can optimize the two units together.
When I "merge" the two files together, I have to ensure that the variables do not have the same name in the merged function "units(.)". That could be solved by renaming all variables in unit1(x1,z) with a prefix "unit1_.". This part is what I seek help to do :)
Stephen23
Stephen23 le 24 Sep 2015
Modifié(e) : Stephen23 le 24 Sep 2015
Why is it required to "merge" these functions together? Are the functions identical?
It is not clear why this "merge" might be desirable: most programming best-practice recommends encapsulation of functionality, and the use of functions for code that needs to be repeated. Separate, smaller functions are easier to write, easier to bug-fix, and much easier to test. Merging them into one large file does not seem to have any particular advantages, yet has the disadvantage that the code now will have "indexed" variable names, which are meaningless and poor programming practice.
I agree 100 %. The reason is that I am using the package cvx (cvxr.com) where as far as I can see, you need all code in one big file in order for this optimization toolbox to work.
Therefore, the only way to merge the two individual functions is to do it kind of manually as text...
Stephen23
Stephen23 le 24 Sep 2015
Modifié(e) : Stephen23 le 24 Sep 2015
One file is a totally different thing to having multiple functions: MATLAB actually has no (practical) restriction on how many functions can be saved in one Mfile:
Why not just add those functions as local functions in the same Mfile?

Connectez-vous pour commenter.

 Réponse acceptée

Jan
Jan le 24 Sep 2015
Modifié(e) : Jan le 24 Sep 2015

0 votes

You need a powerful parser, which can distinguish names of variables from (shadowed) functions, strings and longer names, which contains the string as a part only.
Most likely somebody has written such a thing already and published it in the FEX. What about < http://www.mathworks.com/matlabcentral/fileexchange/15924-farg--a-pedestrian-m-file-parser-showing-all-used-functions--syntax> It should contain all you need. But the modification of the code to replace the strings is not trivial.
I guess that solving the problem in the editor is much faster than creating a powerful parser as a program. Using an automatic tool is only useful, if the codes are large and complicated. And especially in this case, finding potential bugs of the parsing+replacing procedure is very hard. I expect, that the required time for validating and debugging will exceed the advantage in runtime massively.
The efficiency of a program is determined by the time required to solve the problem, not by the runtime only.

1 commentaire

Thanks for your input, Jan. It makes sense - I had just hoped there was a way to exploit the Matlab editor's functionality to change variable names. But from what you say, that is not the case.
Thanks for your input :)

Connectez-vous pour commenter.

Plus de réponses (2)

If you want your code to be able to automatically detect the variables in a file, you're going to need some syntax parser. There is actually one shipped with matlab, mtree, but it is completely undocumented so you'll have your work cut out. mtree may also completely change or be removed in future version as it's not supported by mathworks.
Anyway, the following will give you the list of variable names and function names in a file. There may be a way to differentiate between variable and functions but you'll have to work that out yourself:
parsetree = mtree('main.m', '-file');
treeids = parsetree.mtfind('Kind', 'ID'); %ID are all variables and functions used by the file
idstrings = unique(treeids.strings);
isbuiltin = cellfun(@(id) exist(id, 'builtin') == 5, idstrings); %an easy way to at least remove matlab built-in functions from the list
nonbuiltinid = idstrings(~isbuiltin)
Once you've got the list of variables to replace, you can use fileread to read the whole file at once and strrep or regexprep to perform the replacement.
However, neither a, b, c or main_a, main_b, main_c are good variable names. None of them convey the purpose of the variable.
Furthermore, if the code is properly written, there should be some comments / documentation stating the purpose of each named variables, so you would also have to edit the documentation.

3 commentaires

There are a lot of builtin functions that people like to override with variables. Especially "sum", and "image"
Jan
Jan le 24 Sep 2015
Replacing the string in the file directly would affect quotes strings also, and longer names, which contain the replaced part. In ths OP's case changing "c" to "main_c" would destroy "function".
Indeed, my suggestion of using strrep or regexp was a bit flawed. On the other hand, the mtree parser can also give you the position of the tokens. In my example above:
treeids(~isbuiltin).position
With regards to variables shadowing built-in functions, I went with the assumption that someone capable enough to understand and manipulate the output of mtree has enough experience with matlab to know not to do this sort of things.

Connectez-vous pour commenter.

Benjamin
Benjamin le 24 Sep 2015
Modifié(e) : Benjamin le 24 Sep 2015

0 votes

Thanks for this great suggestion, Guillaume.
As I see it, the parser you suggest is able to find all variable names in the file. That is great, but that could also have been solved by just running "whos" in the end of the function, right?
Once we have the list of all file names, the complicated thing is using strrep or regexprep correctly. If for example you have a variable called "price" and one called "price_max" then when you replace "price" with "unit1_price" you will also edit the variable "price_max" and potentially also functions and what not.
I was hoping for a way to directly use Matlab to replace variables. Since it can highlight variables in a file and replace these directly in the editor, there must be a way that Matlab understands what is a variable and what is not.
Of course you are right that the comments with variable names will not be changed, but I can live with that.
Thanks again:) Ben

2 commentaires

Jan
Jan le 24 Sep 2015
No, whos does only find the defined names. But a variable could be created inside an IF-branch, which did not run for the current values. The parser finds these variables also.
Makes sense - thanks :)

Connectez-vous pour commenter.

Catégories

En savoir plus sur Variables dans Centre d'aide et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by