# Tag Info

16

While I agree that the debugging tools could have been better developed by now, let me just throw in a few notes and links. Function chaining (f[g[h[...]]]): I'd argue that this is a good thing. Why: Functions return expressions, which are immutable. You don't introduce as much state (or at all), as in imperative languages. This makes it easier to debug ...

15

While I wait for better answers from some very knowledgable people in the matter on the site, I'll write what I'm thinking... I think that most of your problems are due to lack of practice with functional thinking rather than lack of debugability itself. I think one that on the contrary, one of the advantages of programming functionally is that the state ...

15

Two of the most common error messages that users encounter when working with parts of lists are Part::partd and Part::partw (look up Message for the error message syntax). Both of these are because the user is trying to access an invalid part of the expression (the "object" referred to in the error message), but there's a subtle difference between the two: ...

14

QuantityForm (and some other formatting functions) issues messages at typesetting instead of evaluation, and Trace is generating output that is in an unevaluated state, which QuantityForm isn't expecting. Here's a couple of similar examples: Trace[Block[{form = "LongForm"}, QuantityForm[Quantity[1, "Meters"], form]]] Trace[Block[{digits = 3}, ...

10

The function Shuffle is not defined. If you define it (say, replace it with RandomSample) it works. Apparently, Rotate in the latter part of the code is being applied to the output of a function that uses edgeNoise which, in turn, (because Shuffle is undefined) is producing the error message you are seeing. To replicate what is happening in a simple setting ...

6

Following R.M's suggestion, and shamelessly lifting code from the Wizard’s fine answer there, you can use Stack[] and get the following: SetAttributes[withTaggedMsg, HoldAll] withTaggedMsg[] := Function[, InternalInheritedBlock[{MessagePacket}, Unprotect[MessagePacket]; MessagePacket[name__, BoxData[obj_, form_]] /; ! TrueQ[$tagMsg] := ... 5 Here's another, reliable way: messages = {} clearMessages[] := messages = {} collectMessages[m_] := AppendTo[messages, m] InternalAddHandler["Message", collectMessages] Then do clearMessages[] 1/0; 0/0; messages InternalRemoveHandler["Message", collectMessages] Reference and details: How to abort on any message generated? 5 What you look for is the function Check which will give you the possibility to implement what you ask for in several variants, the most simple probably be this: success=Check[Import["test1.txt", "Table"];True, False] See the documentation of Check for more details... 4 I would do this: DefFn[f_[args___], body_] := lhs : f[args] := WithStackFrame[lhs, body]; Then make WithStackFrame HoldFirst and do de-structuring there. For example: SetAttributes[WithStackFrame, HoldFirst] WithStackFrame[f_[args___], expr_] := Print[{f, {args}}]; If for some reason this were unacceptable I would do: DefFn[f_[args___], body_] := ... 4 You need a parser for the argument patterns. I wrote a simplistic one for this answer. I will reproduce it here to keep things self-contained: splitHeldSequence[Hold[seq___], f_: Hold] := List @@ Map[f, Hold[seq]]; getFunArguments[Verbatim[HoldPattern][Verbatim[Condition][f_[args___], test_]]] := getFunArguments[HoldPattern[f[args]]]; ... 4 Simply you could use$MessagePrePrint to get the "fillers" and $MessageList as you did to get the message name they belong to:$MessagePrePrint = Sow; Reap[ Module[{}, 1/0; 0^0]; $MessageList ] {{Power::infy,Power::indet},{{1/0,0^0}}} For complete control you could go low-level and intercept MessagePacket as I did for: Prepend Information to Warning ... 3 You could always capture the information directly, myMessageList = {}; InternalInheritedBlock[{Message,$InMsg = False}, Unprotect[Message]; Message[msg_, vars___] /; ! $InMsg := Block[{$InMsg = True}, AppendTo[myMessageList, {msg, vars}]; Message[msg, vars] ]; (* code to run *) Module[{}, 1/0; 0^0] ]; myMessageList (* ...

2

You can use Messages[foo] to get the text of any message. With that, we can proceed as follows to extract the text of the messages that were last generated: Module[{}, 1/0;0^0]; msg = \$MessageList; (* last errors *) With[{messages = ReleaseHold@ DeleteDuplicates[# /. HoldPattern@MessageName[s_, _] :> Messages@s] &}, # /. messages@#] ...

Only top voted, non community-wiki answers of a minimum length are eligible