3
$\begingroup$

I would like to simplify some database notation, and I'm doing some tests with UpValues for that.

For example, if I set this Upvalue fot tab1:

tab1 /: tab1.column1 = 1

When I evaluate

tab1.column1

I get 1 as expected. But if later I set column1 = "x", when I evaluate it again, I get tab1."x" instead of 1 as I need.

There is some way that I can change this behavior? So I could get 1 and prevent variables name conflict?

Update

To avoid misinterpretation here is the evaluation sequence.

Quit the kernel and evaluate:

tab1 /: tab1.column1 = 1;
column1 = "x";
tab1.column1 

The result is tab1."x" in the first evaluation.

$\endgroup$
5
  • $\begingroup$ I get 1, as expected, in version 9.0.0 (Windows Vista). $\endgroup$
    – kglr
    Feb 4, 2013 at 0:00
  • $\begingroup$ @kguler Hi.. Strange behavior... see post update. $\endgroup$
    – Murta
    Feb 4, 2013 at 0:21
  • $\begingroup$ I can't reproduce either of the reported behaviors. On OS X, V9.0.0, I get tab1."x" for all evaluations of tab1.column1. That's what I would expect because I think the ownvalue for column1 is in inserted into Dot before tab1 is checked for upvalues. $\endgroup$
    – m_goldberg
    Feb 4, 2013 at 0:59
  • $\begingroup$ @m_goldberg it's this. The if you do Unprotect@Dot; SetAttributes[Dot, HoldAll] it will works as I need, but now I'm looking for some way to do that without use Unprotect@Dot (I don't know if it's possible). Another test is tab1.Unevaluated@column1. Tks. $\endgroup$
    – Murta
    Feb 4, 2013 at 1:06
  • $\begingroup$ @Murta Very closely related (perhaps a duplicate?): mathematica.stackexchange.com/questions/4161/… The trick is to create a localized scope for the modifications using InternalInheritedBlock` $\endgroup$
    – Ajasja
    Feb 4, 2013 at 12:58

3 Answers 3

4
$\begingroup$

You could do:

Unprotect[Dot];
SetAttributes[Dot, HoldAll]

Then

   tab1 /: tab1.column1 = 1 ;
   column1 = "x";
   tab1.column1

returns 1

Is this what you want?

$\endgroup$
6
  • $\begingroup$ Yes!.. it's this! But it's safe? There is some way to do it in the moment of define the UpValue, (without change Dot)? $\endgroup$
    – Murta
    Feb 4, 2013 at 0:31
  • $\begingroup$ I was thinking in something like tab1 /: Dot[tab1, x_] := Dot[tab1, Unevaluated@x] but it does not works. $\endgroup$
    – Murta
    Feb 4, 2013 at 0:53
  • 1
    $\begingroup$ It's safe. But why do you really want to do this? I would rather invent new Mathematica or DatabaseLink - like functions to do what you want. $\endgroup$ Feb 4, 2013 at 1:10
  • $\begingroup$ You can see the application in the Updated part of this post. I really don't like the way I handle database table today. I'm seeking some way to make the code better. $\endgroup$
    – Murta
    Feb 4, 2013 at 1:23
  • 1
    $\begingroup$ Hi Rolf!.. I just discovery that Unprotect Dot is dangerous. Today I discovery that DateRange do not work if we set SetAttributes[Dot, HoldAll] $\endgroup$
    – Murta
    Feb 4, 2013 at 14:07
4
$\begingroup$

You could introduce your own notation. Something like the following.

SetAttributes[qualifed, HoldAll]
Needs["Notation`"]
Notation[ParsedBoxWrapper[
  RowBox[{"u_", "∘", "v_"}]] \[DoubleLongLeftRightArrow] 
   ParsedBoxWrapper[RowBox[{"qualifed", "[", RowBox[{"u_", ",", "v_"}], "]"}]]]
TagSetDelayed[qualifed, qualifed[u_, v_] = val_, TagSet[u, qualifed[u, v], val]]

tab1∘col1 = 1; tab1∘col1

1

col1 = 42; tab1∘col1

1

tab1∘col1 = 42; tab1∘col1

42

I'm using \[SmallCircle] () in place of dot (.). It can be entered with [esc]sc[esc]. I've tested this only a little. I'm not sure it's foolproof.

$\endgroup$
1
  • $\begingroup$ Interesting approach. Tks! $\endgroup$
    – Murta
    Feb 4, 2013 at 4:03
2
$\begingroup$

Are you sure you're not looking for this:

tab1 /: tab1.column1_ := 1;

That is whatever column1 binds to rather than the literal column1?

this way

tab1."x"

evaluates to

1

$\endgroup$
2
  • $\begingroup$ Today I know that use columns names as symbol instead of strings create a lot of troubles. But tks +1 $\endgroup$
    – Murta
    Dec 31, 2014 at 10:36
  • $\begingroup$ But this approach would also work with symbols: tab1.anothercolumn evaluates to 1 as well $\endgroup$
    – Carlo
    Dec 31, 2014 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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