Mathematica 9 was recently released, and unfortunately

**this does not work anymore in Mathematica 9**. (See below for an experimental method for version 9.) If you have a copy of Mathematica 8 or earlier, however, you can prevent this attribute from being set on imported symbols. You simply need to take advantage of a loophole in the way Mathematica imports package files, encoded ones included.

Normally, when you load a package file, you do something like Get["package.m"]. When you do this, it keeps user definitions of symbols, and respects them when reading in the source code. So all we need to do is redefine Locked to an empty Sequence, so it will be automatically omitted from any lists it appears in. The Locked attribute is protected, but isn't itself Locked until Mathematica 9.

Here's the code you need to run before loading the package (put it in your init.m):

Unprotect[Locked]

Locked = Sequence[]

Now the package will be imported with everything unlocked.

One potential problem with this is that a clever programmer might see this coming and remove your definition of Locked at the beginning of the package. We could Protect it, but the package could still Unprotect it. Say, isn't there an attribute that prevents this?

In case it wasn't obvious, the solution is to Lock your new definition of Locked. I love the irony here, by the way. But remember, we redefined Locked to be harmless, didn't we? So the solution to this is kind of tricky.

Mathematica includes a function called Block. What this function does is let you execute code using temporary values for variables which are then reset to what they were before. If no value is given for a variable, it temporarily clears that variable's definition. Normally this function resets the symbol's attributes as well, but it doesn't if the Locked attribute becomes set during execution, so this still works.

So the new code would be:

Unprotect[Locked]

Locked = Sequence[]

Block[{Locked}, Attributes[Locked] = {Protected, Locked}]

Now when the package loads, you'll probably see something like this, but the package will still be imported just fine.

Protected::locked : Symbol Locked is locked.

ClearAll::locked : Symbol Locked is locked.

All that's left to do now is un-ReadProtect the functions you want to see. Now that they aren't Locked, this won't be a problem. Have fun! :-)

**Edit:**In hindsight, it may be possible for a package to do the same thing with Block. I imagine I would have tested that, but I don't remember for sure, and unfortunately I don't have Mathematica 8 installed anymore, so I can't test now to be sure. Luckily, however, the method described below should work as well.

**Update:**It is also possible to actually rename the Locked attribute internally, which does work on Mathematica 9, as well as 10. This does have some side effects however; for instance, if a package tries to add that attribute using SetAttributes,

*none*of the given attributes will be added. But at least you'll still be able to un-ReadProtect whatever you want. All you have to do is open mathdll.dll (located in [your Mathematica install directory]/SystemFiles/Kernel/Binaries/[your platform folder]) in a hex editor. Then search for the string "Locked" in the file. Make sure it's not part of something longer, like "LockedStack". Find one where it just says "Locked". Then just change it to some other six bytes that won't get in the way.

**Yet another workaround:**If you just want to see the definitions of functions, encasing the package's Get in Trace[] will also show some definitions, based on my testing. The ideal solution, of course, would be a method of decoding packages encoded using Encode, but I haven't been able to figure it out.

## 8 comments:

Have you actually been able to make this theory work on 9?

@Anonymous I've never actually come across any packages that make use of this "feature", to be honest, but it has worked with some small test "packages" I made. (The Sequence trick doesn't work in 9, but the mathdll one does.)

What about v10 on a mac, which file would I edit?

@Anonymous: I'm not sure. Try right-clicking Mathematica.app and selecting "Show Package Contents", and looking in a similar location for a file with a .dylib extension instead.

Post a Comment