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.

In adapting some plotting functions to utilize the PlotLegends option of version 9, I came across the following errors:

f[x_] := Legended[Plot[Sin[t], {t, 0, Pi}], x]
f[1];
Information[f]

TextForm[First::first: StandardForm[Short[Shallow[HoldForm[{}], {10, 50}], 5]] has a length of zero and no first element. >>]

This is just a toy example for a more complex situation where I can't directly use the PlotLegends option but have to use Legended explicitly.

What is the best way to catch this error when a user invokes the above or types ?f to see the code for this function. It seems the output of Definition works as expected (it formats the Legended contents, and that happens for other constructs such as Framed too).

share|improve this question
1  
For the error in ?f, specifying usage message is enough f::usage = "bla";. –  swish May 5 '13 at 20:48
    
Wierd.. I can reproduce the problem at first time. But after doing some tracing, I quit the kernel, then the problem is gone! I restarted the whole mma, still no problem now! –  Silvia May 5 '13 at 20:52
    
@Silvia Yeah, me too! Weird indeed... –  swish May 5 '13 at 20:57
1  
Mmm not sure whether this one needs to be reported as a bug or exorcized –  belisarius May 5 '13 at 21:07
1  
@swish Guess evaluating f introduced something to box functions. Check this: System`Dump`makeusageboxes[f[x_] := Legended["123", x]]. –  Silvia May 5 '13 at 21:14

1 Answer 1

up vote 5 down vote accepted

I Trace-ed the Information[ f ] command both before and after an invocation of f (with a simpler definition f[x_] := Legended["123", x]). By comparing the results, I found a function System`Dump`makeusageboxes:

trace comparison

which reduces to another function BoxForm`MakeBoxesWithTextFormatting:

Attributes[BoxForm`MakeBoxesWithTextFormatting] = {HoldAllComplete}

BoxForm`MakeBoxesWithTextFormatting[BoxForm`args___] := 
          Block[Evaluate[BoxForm`$TextFormattingForms], 
                Block[{BoxForm`UseTextFormattingQ = True}, MakeBoxes[BoxForm`args]]]

By setting BoxForm`UseTextFormattingQ to False (which is its default global value), the problem seems to be bypassed:

Unprotect[BoxForm`MakeBoxesWithTextFormatting]

BoxForm`MakeBoxesWithTextFormatting[BoxForm`args___] := 
 Block[Evaluate[BoxForm`$TextFormattingForms], MakeBoxes[BoxForm`args]]

Protect[BoxForm`MakeBoxesWithTextFormatting]

correct result

Edit

As it might be safer not to modify system functions, here is another possible workaround (the disadvantage is an extra UpValue item):

f /: Information[f, opt_] := 
 Block[{Internal`ConvertFormTest = (InputForm &)}, Information[f, opt]] /; 
  Internal`ConvertFormTest[] === None

Information[f]

I don't know why, but somehow Internal`ConvertFormTest[] is called after an invocation of f. Playing around it reveals its connection to some box formatting.


trace comparison 2

share|improve this answer
    
Unfortunately, your edited solution doesn't work with my original function. And your first solution (using Unprotect) still doesn't work with the function I defined in this answer which motivated my question. But certainly some kind of UpValues solution will be the way to go, even if it has to be more hand-tuned... so I upvoted this. I'll wait a little more before accepting it. –  Jens May 6 '13 at 3:16
    
@Jens Hmm.. More and more looks like a bug, I guess? Will try digging deeper tomorrow.. –  Silvia May 6 '13 at 15:31
    
I agree it behaves like a bug. Would you mind adding the bug tag to the question (so I don't get in trouble for doing it myself)? –  Jens May 7 '13 at 2:38
    
@Jens Of course not. Done. –  Silvia May 7 '13 at 5:12

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.