Message Boards Message Boards

1
|
2561 Views
|
6 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Resolved: Given a symbol, how do I "strip" off the context prefix?

Posted 1 year ago

The following issue is now resolved -- with thanks going to @Eric Rimbey for pointing out my mis-use of the form Needs["context" -> "alias"] prevented my paclet symbols from being loaded into $Context. Attached is the working example where using Needs["context"] solves my issue.

The original question follows.


In my paclet, I have a function that extracts relevant symbols from an equation to return a sorted symbols list. But my implementation strategy fails when anyone calls my paclet function from a different namespace context. Is there a means of creating a function were I can add a blank sequence for the context? Or, is there a more generalized strategy for handing symbols between different contexts?

Implementation:

pSort[ M ] = 1;
pSort[ w[id_] ] := 100 + id;
pSort[ A[id_] ] := 200 + id; 

extractSymbols[ equation_ ] :=
      Block[{varsAndCosVars, deDupedAndAll},
       varsAndCosVars = (Variables @ equation) /. (Cos[vars_] :> Variables @ vars);
       deDupedAndAll = 
    DeleteCases[DeleteDuplicates[Flatten[varsAndCosVars]], t]];

Test:

testEq1 = A[2]*Cos[w[2]*t] + A[1]*Cos[w[1]*t] + M;
Sort[extractSymbols @ testEq1, pSort[#1] < pSort[#2] &]

Expected Result:

{M, w[1], w[2], A[1], A[2]}

Problem: While the above does work in the paclet context space, it fails when extractSymbols is invoked from another context where the Symbols in the equation are unique to caller's context space.

POSTED BY: A. Chase Turner
6 Replies

Does adding t as a argument work for you?

extractSymbols[ equation_ , t_] :=
      Block[{varsAndCosVars, deDupedAndAll},
       varsAndCosVars = (Variables @ equation) /. (Cos[vars_] :> Variables @ vars);
       deDupedAndAll = 
    DeleteCases[DeleteDuplicates[Flatten[varsAndCosVars]], t]];

If you want an "operator form," you could define it thus:

 extractSymbols[t_][ equation_ ] := ...

Then extractSymbols[t] @ equation.

POSTED BY: Michael Rogers

Thank you -- I had not previously appreciated how to use the operator form and now I know!

POSTED BY: A. Chase Turner
Posted 1 year ago

Okay, several things going on here. First, from the documentation for Needs (emphasis added)

Needs["context`"->"alias`"] adds "alias`"->"context`" to $ContextAliases, providing the ability to use a shorter or easier to type alias to access symbols in that context.

Contexts loaded with this form are not added to $ContextPath.

Unless you have some specific need that you haven't explained yet, you will want to have the $ContextPath updated so that your new package context will get searched. This is how you will avoid prefixing all of your new symbols with the full context. So, just do this:

Needs["ContextA`" , FileNameJoin[{NotebookDirectory[], "ContextA.wl"}]]

Now, we need to get your new symbols into the ContextA` context. The way to do that is to expose them after BeginPackage["ContextA`"] and before Begin["`Private`"].

Read the documentation for BeginPackage and Begin. It explains how each affects the context and context path.

So, you could do something as simple as this:

extractSymbols::usage = "Extracts variables from models of a particular form, minus the t variable";
pSort::usage = "symbol precidence, with sub-sort on component ID";
M;w;A;t;

Now, get rid of all instances of "a`" (your alias), and your tests pass.

POSTED BY: Eric Rimbey

Bingo -- Thank you for helping me to see where I had gone wrong. Per your suggestion, all is now working as expected!

POSTED BY: A. Chase Turner
Posted 1 year ago

You should show us how exactly you set up your paclet (e.g. how you used BeginPackage, Begin, or whatever). But I suspect that the problem is to do with your symbols M, w, A, and t. You should declare those symbols in your package context. pSort and extraceSymbols should also be declared, but based on the way you asked the question I assume that you already declared those.

POSTED BY: Eric Rimbey

Please save "ContextA.wl" in the same folder as "CallsContextA.nb". Then, Open "ContextA.wl" and confirm the VerificationTests work as expected. Open "CallsContextA.nb" and observe VerificationTests will fail.

How should I write ContextA's functions so they work with Symbols {M, A, w, t} from any context -- without forcing ContextA to define them as Global? NOTE: Assuming a .nb has a "Needs["ContextA" -> "a"], I do not want there to be a solution where equations have to be written as follows:

a`A[2]*Cos[a`w[2]*t] + a`A[1]*Cos[a`w[1]*t] + a`M
POSTED BY: A. Chase Turner
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract