Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

How to embed and call the correct embedded modules inside another Module?

Say:

importNames:=Module[{},  
    CWC=FinancialData["CWC.L","Jan. 1, 2007"];  
    KON=FinancialData["AH.MI","Jan. 1, 2007"];  
    IFX=FinancialData["IFX.DE","Jan. 1, 2007"];  
    ISYS=FinancialData["ISYS.L","Jan. 1, 2007"];  
    LAD=FinancialData["LAD.L","Jan. 1, 2007"];  
]  

checkLength:=Module[{},  
    LCWC=Length[CWC];  
    LKON=Length[KON];  
    LIFX=Length[IFX];  
    LISYS=Length[ISYS];  
    LLAD=Length[LAD];  
]  

plotNames:=Module[{},  
    plotCWC=DateListPlot[CWC];  
    plotKON=DateListPlot[KON];  
    plotIFX=DateListPlot[IFX];  
    plotISYS=DateListPlot[ISYS];  
    plotLAD=DateListPlot[LAD];  
]

Remove[corrMat];  
Remove[importNames];  
Remove[checkLength];  
Remove[plotNames];   

corrMat:=Module[{},    
    importNames;  
    checkLength;  
    plotNames;  
]  

corrMat  
plotNames  
plotKON  

When doing plotKON, how do I know it is calling from within the base definition of plotNames, or it is called from corrMat.plotName.plotKON (using java syntax)?

share|improve this question
    
I would encourage you to look at the details of how I formatted my answer by clicking on the edit link below it. –  rcollyer Dec 1 '12 at 15:56
1  
I actually think that this is an interesting question, although not enough effort was put into formulating it properly. –  Leonid Shifrin Dec 1 '12 at 17:19
    
@sebastianc. considering the anger that has been generated by your refusal to format your questions, I have to ask, did you look at how I formatted my answer? Did you read the FAQ as halirutan suggested? Have you done any due diligence in being a good member of the community? If not, why should we continue to answer? –  rcollyer Dec 2 '12 at 1:11
2  
@sebastianc. Your many questions demonstrate that you have not yet achieved a basic understanding of how Mathematica works. You still seem to think it is a procedural programming language like C or Basic. It isn't. Please invest some time in studying the basics. –  m_goldberg Dec 2 '12 at 2:12

2 Answers 2

Easy: Module only localizes the variables that are specified in the initial list, so plotKON is global precisely because the list is empty. Your use of Module does nothing here, and the code could be equivalently written

importNames:=(
  CWC=FinancialData["CWC.L","Jan. 1, 2007"];
  KON=FinancialData["AH.MI","Jan. 1, 2007"];
  IFX=FinancialData["IFX.DE","Jan. 1, 2007"];
  ISYS=FinancialData["ISYS.L","Jan. 1, 2007"];
  LAD=FinancialData["LAD.L","Jan. 1, 2007"];
) 

(* etc ... *)

and the behavior will be identical.

share|improve this answer
    
Hi rcollyer thanks but that is not my question, I asked how to differentiate calling a base definition vs derived definition –  sebastian c. Dec 1 '12 at 16:18
1  
While that is true, there are no derived definitions present in your code: it is all global. importNames and the like only provide convenient vehicles for setting plotKON, etc. Because of that, when you call corrMat; plotNames; plotKON, plotKON is the global definition, and there is no local definition akin to corrMat.plotName.plotKON. Also, if you were to localize plotKON, etc., you could not access them as the only thing akin to what you are asking are packages and contexts. I'd suggest you look into them. –  rcollyer Dec 1 '12 at 16:27

My interpretation of the problem

You should avoid designs which would require that your inner function needs that kind of knowledge (that is, from where it is called), whenever possible. For what follows, assume that the problem is set up as follows:

ClearAll[f,ff,g,h,codeBefore,codeAfter];
f[]:= Module[{},codeBefore;g[]; codeAfter];
ff[]:= Module[{},codeBefore;g[]; codeAfter];
g[]:= Module[{},codeBefore;h[]; codeAfter];
h[]:= (Some code that needs needs to know whether it is called inside f or ff)

Some ways out

Here are some different things you can do.

Pass arguments explicitly

One straightforward way of doing this is passing extra arguments explicitly:

ClearAll[f,ff,g,h,codeBefore,codeAfter];
f[]:= Module[{},codeBefore;g[f]; codeAfter];
ff[]:= Module[{},codeBefore;g[ff]; codeAfter];
g[fn_]:= Module[{},codeBefore;h[fn]; codeAfter];
h[fn_]:= Print["Called from ",fn];

which you test with e.g.

{f[], ff[]}

Use local dynamic environments (Block)

There are indeed cases where this is inconvenient, since you have to pass along the arguments which don't make sense for intermediate functions in the chain. In such cases, I sometimes use a global variable (say, $environment), but set it semi-locally by using Block, so this would look like

ClearAll[f,ff,g,h,codeBefore,codeAfter];
f[]:= Block[{$environment = {f}},codeBefore;g[]; codeAfter];
    ff[]:= Block[{$environment = {ff}},codeBefore;g[]; codeAfter];
    g[]:= Module[{},codeBefore;h[]; codeAfter];
    h[]:= Print["Called from ", $environment];

which you can test as

{f[],ff[]}

Use the Stack

This method is somewhat fragile, but sometimes you just have no choice. Here is how it may look like:

ClearAll[f, ff, g, h, codeBefore, codeAfter];
f[] := Module[{}, codeBefore; g[]; codeAfter];
ff[] := Module[{}, codeBefore; g[]; codeAfter];
g[] := Module[{}, codeBefore; h[]; codeAfter];
h[] := Print[Stack[][[-9]]]

The problem here is that this will work only if you wrap the code you execute in StackComplete:

StackComplete[{f[], ff[]}]

During evaluation of In[112]:= f
During evaluation of In[112]:= ff

(* {codeAfter, codeAfter} *)

Remarks

Use explicit argument passing whenever possible. When not possible (although many cases where it does not look possible can be redesigned), use local environments. The uses of Stack should be reserved to cases when nothing else helps, and usually the code using Stack looks like a hack, so I'd avoid that if at all possible.

At the same time, I'd like to acknowledge that the problem raised here does indeed exist in practice. The real problem here is that often we would like to pass some parameters from the top-level function f directly to functions much lower down in the execution stack, while by-passing intermediate functions in the function call chain. One good reason to do that may be that those intermediate functions would have to be over-specialized to carry those parameters along, which would hurt re-usability. What I usually do is to try strike a right balance between the lexical and dynamic scoping (variable passing), with the preference given to lexical scoping but keeping an open mind and using local dynamic environments where appropriate.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.