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.

This question already has an answer here:

I have a TagSetDelayed rule associated with, say, tag:

tag/:(tag[key_]=val_):=DoSomething[tag,key,val]
tag[7]=43
(* DoSomething[tag,7,43] *)

I want to modify that rule to do something before what it already does, preserving what it already does. Of course, the following only overrides the existing rule:

tag/:(tag[key_]=val_):=DoSomethingElseBefore[tag,key,val]
tag[8]=44
(* DoSomethingElseBefore[tag,8,44] *)

I'd like, instead, to end up with the result of this:

tag/:(tag[key_]=val_):=(
DoSomethingElseBefore[tag,key,val];
DoSomething[tag,key,val];
);

I'm not sure how to "introspect", i.e. "paste" the existing rule as I redefine the rule, like so:

tag/:(tag[key_]=val_):=(
DoSomethingElseBefore[tag,key,val];
ExistingTagSetDelayedRule[]
);

Edit

I realized I could use ?tag to see a list of associated rules, but how would I extract the RHS of the appropriate form, tag[_]=_?

?tag
Global`tag
(tag[key_]=val_)^:=DoSomething[tag,key,val]
share|improve this question

marked as duplicate by Mr.Wizard Jan 25 at 10:02

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
Coming from a C++/Tcl background I may be using wrong / ambiguous / confusing terms—please do point such out and help me improve my question. –  Andrew Cheong Jan 25 at 3:25
    
You should check the function UpValues –  Rojo Jan 25 at 7:24
    
Related: (27165), (39711) –  Mr.Wizard Jan 25 at 10:02
add comment

1 Answer 1

up vote 1 down vote accepted

One easy method is to use the following construct

tag /: (tag[key_] = val_) := Block[{didBefore = True},
   Print[{tag, key, val}];
   tag[key] = val
  ] /; Not[TrueQ[didBefore]]

and you get

tag[7] = 43

(* {tag,7,43} *)
(* DoSomething[tag, 7, 43] *)

Here, the Print was injected before your actual call. If you are puzzled now, this is OK, because the approach is not obvious. For more information please look in the comments here or read here

To answer your second question:

how would I extract the RHS of the appropriate form, tag[]=?

First you have to know which kind of rule is used. In your case you assigned it to the UpValues of tag

UpValues[tag]
(* {HoldPattern[tag[key_] = val_] :> DoSomething[tag, key, val]} *)

and of course you could (but probably shouldn't) assign these rules directly by using

UpValues[tag] = ...

Sidenote

If you have understand the first approach, then you can write it a bit shorter, without repeating the = call, because this could in reality be more complex

tag /: code : (tag[key_] = val_) := Block[{didBefore = True},
   Print[{tag, key, val}];
   code
  ] /; Not[TrueQ[didBefore]]
share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.