0
xxx[a_] := Module[{b},
   b = a + 2;
   b + 2];
xxx[2]

Is there a way to examine value of b was during last invocation? The underlying issue is that I refactored all of my utilities to use Module[{vars},...] to avoid conflicts, but sometimes the output doesn't make sense and I want to look at intermediates.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Yaroslav Bulatov
  • 7,793
  • 1
  • 19
  • 44
  • Sound like you want to know how to debug, am I correct? 2245 + linked topics. There is also 'debugging' section in https://mathematica.stackexchange.com/questions/18/where-can-i-find-examples-of-good-mathematica-programming-practice/ – Kuba Apr 27 '17 at 19:41
  • I just need the values, those internal variables should be accessible as something like that b$3848, right? – Yaroslav Bulatov Apr 27 '17 at 19:43
  • Depends, Module variables have an attribute Temporary and are cleared after execution if not needed anymore. – Kuba Apr 27 '17 at 19:44
  • I want to print value of b after the function finished. I'm guessing for this I need to disable garbage collection, and also find some way to find what the name of the variable was (is there some object that stores name of recently created vars like b$3848?) – Yaroslav Bulatov Apr 27 '17 at 20:13

2 Answers2

1

I think Trace/TracePrint might be what you are looking for. In:

xxx[a_] := Module[{b},
   b = a + 2;
   b + 2];
TracePrint[xxx[2], b]

Out:

b$508901 (* local variable name of b *)
4 (*b's value *)
6 (*xxx[2]'s result*)
webcpu
  • 3,182
  • 12
  • 17
0

While this is quite a hack (fair warning), you can use the following form to track your module values. Also a fair warning: I haven't tested this extensively, but it should work for simple examples at the least.

HackModules[code_] := Block[{Module},
  With[
    {results = Unique[]},
    SetAttributes[results, Temporary];
    results = {};
    Module[args_List, body_] := With[
      {syms = First@Replace[
         Hold[args],
         {HoldPattern[x_Symbol = y_] :> {HoldPattern[x], Hold[y]},
          HoldPattern[x_Symbol] :> HoldPattern[x]},
         {2}]},
      Do[
        SetAttributes[Evaluate@If[ListQ[s], s[[1, 1]], s[[1]]], Temporary],
        {s, syms}];
      With[
        {vars = Replace[
           Hold @@ List@Table[
             If[ListQ[s], Join[Hold[Evaluate@Unique[]], Last[s]], Unique[]],
             {s, syms}],
           Hold[a_, b_] :> Set[a, b],
           {2}]},
        With[
          {bodyResult = CompoundExpression @@ Join[
             First[Hold @@@ vars],
             ReplaceAll[
               Hold[body],
               MapThread[
                 If[ListQ[#1], First[#1], #1] -> #2 &,
                 {syms, vars[[1, All, 1]]}]]]},
          With[
            {finalVals = MapThread[
               If[ListQ[#1], First[#1], #1] -> #2 &,
               {syms, vars[[1, All, 1]]}]},
            AppendTo[results, Hold[body] :> finalVals];
            bodyResult]]]];
    SetAttributes[Module, HoldAll];
    With[
      {codeResult = code},
      {results, codeResult}]]];
SetAttributes[HackModules, HoldAll];

This basically watches every module call you make and yields a list of {moduleVariableValues, allCodeReturnValue}:

HackModules[
  Module[
    {y = Module[{x = 12},
       x -= 2;
       x + 4]},
    y *= 10;
    y - 40]]

{{Hold[x -= 2; (x + 4) y] :> {HoldPattern[x] -> 10, HoldPattern[y] -> 2},
Hold[z *= 10; z - 80] :> {HoldPattern[z] -> 280}},
200}

The first element of the returned list is a list of delayed-rules where the LHS is the held code (the bodies of the modules) and the RHS is a list of the module variables with their values at the end of the module evaluation.

nben
  • 2,148
  • 9
  • 20