From: Steven Lord on 14 Jan 2010 13:35 "Foo" <foowidget(a)gmail.com> wrote in message news:624af29d-ddbc-401f-b434-873fab612989(a)k17g2000yqh.googlegroups.com... > Grant that I'm stuck with multiply-named variables in the base > workspace, as described > before. It seems like I'm stuck with some messiness somewhere in my > code. Yes, you are. You should copiously comment the code you're going to have to add to do this (along with the rationale for why you're doing it this way) to make things a little easier for those who have to debug and maintain this after you. > Two options are discussed below. > > > So you're both fiddling with the base workspace AND "poofing" variables > > into > > the workspace of procFun? That's going to be VERY tricky to debug when > > (not > > if) something goes wrong. > > > If you MUST do this (as in someone has a gun to your head, or you will > > be > > fired if you don't solve the problem this particular way) you can use > > EVALIN > > and ASSIGNIN in combination. > > The function assignVars would read variables from two levels up and > assign variables > one level up. That doesn't really seem so messy given that it's a > private subfunction of > procFun. Seriously, is it more awful than the alternate solution > discussed below? You seem to be focused on going between levels using just the 'caller' relationship. If you MUST have assignVars read from the base workspace and create variables in its calling function, DO NOT call EVALIN and specify that you want to evalute the expression in the 'caller' workspace, but instead evaluate it in the 'base' workspace. "Poof"ing variables into a workspace can cause and have caused very difficult to diagnose problems as has been discussed in this newsgroup in the past -- if you search for "poof" or "poofing" you should see some of those discussions. > > I strongly recommend rethinking this approach -- it's GOING to cause you > > pain. Use Bruno's suggestion and pass variables into procFun as input > > arguments. Then you KNOW what their names are inside procFun, and don't > > need to worry about the names of the variables in the base workspace > > conflicting with local variables you use inside procFun, or juggling > > three > > different workspaces at once. > > To implement Bruno's suggestion, I could run a script (not a function) > from the > base workspace that figures out what variables to pass to procFun. > Potentially, a > variable in the script could overwrite a data variable with the same > name. > > So the tradeoff as I see it is: > > assignin/evalin - PROs - no chance of overwriting data. Assuming that your function that calls ASSIGNIN somehow knows what variables exist in the script into which it's assigning and knows not to overwrite them, yes. Just be careful when you modify the script into which it's assigning so that you don't accidentally use a variable name that ASSIGNIN is going to overwrite. > Variable- > sorting code is > neatly hidden away in a subroutine. CON - uses programming practice > that is not > recommended I'd say this CON a bit more strongly than "not recommended", but that's just me. > script at base workspace - PRO - avoids assignin/evalin. Variable- > sorting code is > hidden in script. CON - possible overwriting of data in base > workspace > > Is there a third option that stays inside the operating conditions? > That is, that > data is going to be loaded into the base workspace, and my processing > code must > be launched from a single simple command typed into the command line. I don't know if this stays inside your real operating conditions, but it _technically_ stays within the boundaries you just described. Load your data into a struct array, not individual variables, in the base workspace. Pass that struct array into your processing code, which extracts the fields from the struct array into individual variables if it needs to or uses dynamic field name indexing. % begin myprocessingcode.m function myprocessingcode(S) fn = fieldnames(S); for k = 1:numel(fn) fprintf('Processing "variable" %s.\n', fn{k}); doSomethingWith(S.(fn{k})); end function doSomethingWith(x) disp(numel(x)) % end myprocessingcode.m You can then call this as: myprocessingcode(load('census')) or S = load('census'); myprocessingcode(S) There's no "poofing" of variables in the code above, plus everything stays in one nice neat package. -- Steve Lord slord(a)mathworks.com comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ
From: Susan on 14 Jan 2010 14:47 I want to say thanks to all who have made this an informative discussion. I followed one of the "poofing" threads where the caller was having trouble because he was using assignin to write a variable whose name conflicts with a function name. Other threads, when I searched, were tagged as poofing but I didn't see why. Is there a thread or article somewhere that enumerates the evils of poofing? People in my group have written several handy scripts that use assignin/evalin, and to my knowledge they haven't caused problems despite frequent use by multiple users. That said, I'm interested to know about the hazards mentioned here. Susan
From: Matt J on 14 Jan 2010 15:11 "Susan " <foowidget(a)gmail.com> wrote in message <hinsbo$60d$1(a)fred.mathworks.com>... > I want to say thanks to all who have made this an informative discussion. > > I followed one of the "poofing" threads where the caller was having trouble because he was using assignin to write a variable whose name conflicts with a function name. Other threads, when I searched, were tagged as poofing but I didn't see why. Is there a thread or article somewhere that enumerates the evils of poofing? > > People in my group have written several handy scripts that use assignin/evalin, and to my knowledge they haven't caused problems despite frequent use by multiple users. That said, I'm interested to know about the hazards mentioned here. ================ Conflict with function names is the main problem that I know of. Since programmers will infrequently choose a variable that coincides with a function name, it would explain why you haven't hit this pitfall, in spite of habitual use of assiginin/evalin Here are a few more: (1) It would also be a problem if you own the MATLAB Compiler (or think you might one day want to) and want to use it to convert your M-code to a stand-alone executable. The MATLAB Compiler has no way of detecting poofed variables and will give you compilation errors. (2) if you stop your code in debug mode, and skip through the stack using dbup() and dbdown() it can be hazardous to call evalin/assignin or functions which call them. This is because even though you change workspaces using dbup and dbdown, the workspace as far as evalin/assignin is concerned is wherever the debug breakpoint occured. So, you can end up poofing variables into the wrong workspace. (3) One final example is that nested functions and other so-called Static Workspaces will not allow you to poof variables as you will see if you run the example function below. function test nestedfnc; function nestedfnc eval('X=1;') end end >> test ??? Attempt to add "X" to a static workspace. See MATLAB Programming, Restrictions on Assigning to Variables for details. Error in ==> tst>nestedfnc at 7 eval('X=1;') Error in ==> tst at 3 nestedfnc;
First
|
Prev
|
Pages: 1 2 3 4 Prev: Hydraulic Pump transfer function. Next: using rough sets for noise filtering |