当 DownValues 已经存在时可以阻止 OwnValues 吗? [英] Possible to block OwnValues when DownValues already exist?

查看:35
本文介绍了当 DownValues 已经存在时可以阻止 OwnValues 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于已经分配了与名称a"相关联的 DownValues 的情况,是否有一种可接受的方法来阻止将 OwnValues 分配给相同的名称?(我最初是在玩弄某人实现数据字典的尝试时遇到这个问题的.)

For cases where one has already assigned DownValues associated with the name 'a', is there an accepted way to block the assignment of OwnValues to the same name? (I originally came across this issue while playing with someone's attempt at implementing a data dictionary.)

以下是我要避免的意思:

Here's what I mean to avoid:

Remove[a];
a[1] := somethingDelayed
a[2] = somethingImmediate;
DownValues[a]
a[1]
a[2]

返回...

{HoldPattern[a[1]] :> somethingDelayed, 
 HoldPattern[a[2]] :> somethingImmediate}
somethingDelayed
somethingImmediate

现在如果我们要评估:

a = somethingThatScrewsUpHeads;
(* OwnValues[a] above stored in OwnValues *)
a[1]
a[2]

我们得到...

somethingThatScrewsUpHeads[1]
somethingThatScrewsUpHeads[2]

是否有一种简单/灵活的方法可以防止 DownValues 中任何 Name 的 OwnValues?(让我猜猜......这是可能的,但会影响性能?)

Is there an easy/flexible way to prevent OwnValues for any Name in DownValues? (Lemme guess... it's possible, but there's going to be a performance hit?)

推荐答案

我不知道这是否是一种接受"的方式,但您可以定义一个规则来阻止 SetSetDelayed 从作用于 a :

I don't know if this is an "accepted" way, but you could define a rule that prevents Set and SetDelayed from acting upon a:

Remove[a];
a[1] := somethingDelayed
a[2] = somethingImmediate;

a /: HoldPattern[(Set|SetDelayed)[a, _]] := (Message[a::readOnly]; Abort[])

a::readOnly = "The symbol 'a' cannot be assigned a value.";

有了这个规则,任何将 OwnValue 分配给 a 的尝试都将失败:

With this rule in place, any attempt to assign an OwnValue to a will fail:

In[17]:= a = somethingThatScrewsUpHeads;

During evaluation of In[17]:= a::readOnly:
  The symbol 'a' cannot be assigned a value.

Out[17]= $Aborted

In[18]:= a := somethingThatScrewsUpHeads;

During evaluation of In[18]:= a::readOnly:
  The symbol 'a' cannot be assigned a value.

Out[18]= $Aborted

但是,此规则仍将允许 a 的新 DownValues:

However, this rule will still allow new DownValues for a:

In[19]:= a[3] = now;
         a[4] := later

In[20]:= a[3]

Out[20]= now

In[21]:= a[4]

Out[21]= later

性能

该规则似乎对 SetSetDelayed 的性能没有明显影响,大概是因为该规则是作为 上的 up-value 安装的一个.我试图通过执行来验证这一点...

The rule does not seem to have an appreciable impact on the performance of Set and SetDelayed, presumably since the rule is installed as an up-value on a. I tried to verify this by executing...

Timing@Do[x = i, {i, 100000000}]

... 在安装规则之前和之后.时间没有明显变化.然后我尝试在 10,000 个生成的符号上安装与 Set 相关的向上值,因此:

... both before and after the installation of the rule. There was no observable change in the timing. I then tried installing Set-related up-values on 10,000 generated symbols, thus:

Do[
  With[{s=Unique["s"]}
  , s /: HoldPattern[(Set|SetDelayed)[s, _]] :=
      (Message[s::readOnly]; Abort[])
  ]
, {10000}]

同样,即使制定了如此多的升值规则,时间也没有改变.这些结果表明,从性能的角度来看,这种技术是可以接受的,但我强烈建议在您的特定应用程序的上下文中执行性能测试.

Again, the timing did not change even with so many up-value rules in place. These results suggest that this technique is acceptable from a performance standpoint, although I would strongly advise performing performance tests within the context of your specific application.

这篇关于当 DownValues 已经存在时可以阻止 OwnValues 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆