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.

How do I replace content inside a Held expression without local values coming through? For example if you run the following code you get g[2] instead of g[x](the intended form).

x = 2;
Replace[HoldComplete[g["x"]], {
  y_String :> With[{
     eval = Symbol[y]},
    eval /; True]
  }, {0, Infinity}]

The following questions are related

EDIT: Although rm-rf's trick is clever it partially works. His current code adds an additional defer to the current code.

InputForm@HoldComplete[g["x"]] /. 
  s_String :> With[{x = ToExpression[s, InputForm, Defer]}, x /; True]

returns HoldComplete[g[Defer[x]]] instead of HoldComplete[g[x]]. Ultimately you could strip out the Defers which is likely what I will end up doing.

share|improve this question

3 Answers 3

up vote 5 down vote accepted

You're needlessly complicating things. The third argument of ToExpression with the Trott–Strzebonski can be used to do this:

HoldComplete[g["x"]] /. s_String :> 
    With[{x = ToExpression[s, InputForm, Defer]}, x /; True]
(* HoldComplete[g[x]] *)
share|improve this answer
    
Sequence might be used to get around this issue but I'm just running off intuition. –  Liam William Sep 15 '13 at 17:36
    
@Liam, if that's a problem why not just strip out the Defer with a replacement /. Defer[x_] :> x –  Simon Woods Sep 15 '13 at 17:36
    
I modified your code slightly to the following. It works quit well. You are quit right I will stop posting partial questions especially to chat. –  Liam William Sep 15 '13 at 21:03

I hope that you will give a more complete example in the question if this is not adequate. As it stands I don't see the need to mess with context but given the earlier questions I suspect your example is not representative of what you actually wish to accomplish.

For the given example you could use something like this:

x = 2;

Module[{h},
  SetAttributes[h, HoldAllComplete];
  HoldComplete[g["x"]]
    /. y_String :> RuleCondition[h @@ MakeExpression@y]
    /. h[x___] :> x
] // FullForm
HoldComplete[g[x]]

This is better than stripping all Defer or HoldComplete heads as it will not strip heads that were not introduced by the replace operation itself.

share|improve this answer
    
+1. Just for fun: Delete[HoldComplete[g["x"]] /. y_String :> RuleCondition@MakeExpression@y, {1,1,0}] –  WReach Sep 16 '13 at 3:13

The following function ReplaceC evaluates the Replace in an alternative context and the strips the context back from the returned value.

ReplaceC[data_, rules_] := ToExpression@Replace[
    ToBoxes[
     With[{body =
        ReleaseHold@Replace[HoldComplete@MakeBoxes[
            Replace[x, rules, {0, Infinity}]
            ],
          HoldPattern[x] -> data, {0, Infinity}]
       }, Block[{$ContextPath = {"System`"}, $Context = "context`"},
       ToExpression@body]
      ]
     ],
    s_String :> StringReplace[s, RegularExpression["^context`"] -> ""],
    {0, Infinity}
    ];

Then you can run the following to get g[x].

ReplaceC[HoldComplete[g["x"]], {
  y_String :> With[{
     eval = Symbol[y]},
    eval /; True]
  }]
share|improve this answer

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.