2011-10-27 43 views
12

如果我们评估这些行一个接一个,x将在上下文cc创建。为什么不使用Begin []工作?

Begin["cc`"]; 
x = 1; 
End[] 

但是,如果我们一起对其进行评估,

(Begin["cc`"]; 
x = 1; 
End[]) 

然后x将在Global创建。尽管这是以下打印cc`

(Begin["cc`"]; 
Print[$Context]; 
End[]) 

什么是这种现象的原因?我的猜测是,上下文只在解析阶段,而不是评估。

用例:我想创建一个调色板Button,它将在“私有”上下文中定义一些符号(如果它们还不存在),以避免与全局冲突。 除了将所有定义放入包文件中并从调色板中加载它们之外,执行此操作的首选方法是什么?? (我想保持调色板自成体系。)

+0

我刚才读该文档是“符号名称的解释取决于上下文'Begin'从而影响输入表达式的分析。”这回答了我的第一个问题。第二个仍然站立。 – Szabolcs

回答

15

符号(及其上下文)在解析时创建,而不是评估。如果我们使用$NewSymbol我们可以有效看到:

$NewSymbol=Print["Name: ",#1," Context: ",#2]&; 

Print["first"]; 
test1; 
Print["last"] 

(Print["first"]; 
test2; 
Print["last"]) 

第一个打印:

first 
Name: test1 Context: Global` 
last 

因为在小区中的每个线被作为一个单独的输入处理。第二个括号使用强制所有三条线被认为是一个输入和打印

Name: test2 Context: Global` 
first 
last 

从中我们可以看出,test2是在Global`上下文中创建发生的任何评估之前。

我认为最简单的方法就是在符号上使用明确的上下文:cc`x = 1

+0

+1,有趣的结果。 – rcollyer

+3

另一个有用的选择是在*评估期间使用ToExpression做一些新的解析*(Begin [“cc'”]; With [{s = ToExpression [“x”]},s = 1]; End [ ];) –

+0

Brett,有什么方法可以使用'$ NewSymbol'来强制在特定的上下文中创建符号,并且扩展名不是默认的? –

2

对于第二个问题,我提及您的this答案,它可以有效地自动执行您列出的步骤(使用ParseTimeNameSpaceWrapper函数)。它可能需要更多的工作才能使它更加健壮,但这可能是一个起点。我偶尔会自己使用这些东西。

+0

'ParseTimeNameSpaceWrapper'仍然没有解决符号的上下文是在parse-time决定的事实,也就是说,如果我做了'ParseTimeNameSpaceWrapper [x]',那'x'仍然会被解释为''Global'x'' ',而不是''MyLocalizedContext'x''。在理解上下文在解析时被选中之后,我认为没有别的办法,只能通过将一些代码放在字符串中并使用“ToExpression”或者从包中读取它来强制重新解析(或者只是编写如布雷特所建议的那样明确地定义上下文,但对于更长的代码,这是很多工作)。 – Szabolcs

+0

@Szabolcs我明白了。也许这个线程可能对您感兴趣,关于解析阶段:http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/c1f4ab24db8a8542 –

0

仅供参考:

(Begin["cc`"]; Evaluate[Symbol["x"]] = 1; End[]) 

cc`x 
1