Archive for 九月, 2006
第十课 把前面的综合起来
现在你已经对写 Smalltalk 代码非常有经验了。你会越来越多的用系统浏览器,而越来越少的用工作空间。然而,在目前我们仍然要使用工作空间来验证我们的代码,然后才把它们移植到系统浏览器里面,以创建更多的方法。这种模式没什么不对,在这一课里,我们仍然这样做。工作空间主要用来在把代码移动到新方法里之前测试一个代码片段是否工作正常。
在本课中,我们将把工作空间里的代码(从日志文件里面收集页面计数的代码)转移到 WebLog 类的一个新方法中去,以便于处理位于整个目录中的日志文件。我们在前面已经做了大量的基础工作(类别、类、协议),因此本课比一开始做这工作时又短又容易。
你会注意到有些代码是冗余的(比如有些方法做几乎相同的事情),你也许想把这些代码合并起来,以使得它们更加通用(高效、可重用);你的感觉非常棒!我们下一课来研究这个话题。
- 启动系统浏览器(通过在 VisualWorks 主启动窗口里点击工具栏第四个工具按钮,或者选择菜单项 Browse>>System )。
- 在包面板(最左边的)里上下滚动,高亮选择 WebLogStats 包。 如果没有找到 WebLogStats 包,你需要从文件里装入进来。在前一课里我们已经把这个包从文件里装入进来了,这课需要使用这个包。
- 确保协议面板上方的 Instance 标签页已被选择。点击 private 协议,你将会看到如下一个窗口:

图 10-1 系统浏览器中的 WebLog 类 - 在 private 协议仍然在选择状态下,如下替换方法区域里的代码:
showPageCounts: aFile
| stream line bag xFound sort out outName|
bag := Bag new.
stream := (logDirectory asFilename construct: aFile) readStream.
[ stream atEnd ] whileFalse: [
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
line := line copyUpTo: $,.
xFound := line findString: ‘.asp’ startingAt: 1.
xFound > 0
ifTrue:[ bag add: line. ]. ].
stream close.
sort := SortedCollection sortBlock: [:a :b| a >= b].
bag valuesAndCountsDo: [ :each :count |
sort add: (Core.Association key: count value: each)].
outName := (logDirectory asFilename construct: aFile) asString. out := (outName, ‘.stats’) asFilename writeStream.
sort do: [ :each | out cr; nextPutAll: each printString.].
out close. - 现在在底面板里单击<操作>菜单,选择 “Accept It” 。方法 showPageCounts: 出现在方法面板里。你将会看到如下一个窗口:

图 10-2 系统浏览器中看到的新方法 showPageCounts - 在 private 协议仍然选择着的情况下,如下更改方法面板中的代码:
getLogFilesForPageCounts| workingDir contents xFound |
Transcript clear.
workingDir := logDirectory asFilename.
contents := workingDir directoryContents.
contents do: [ :each |
xFound := each findString: filter startingAt: 1.
xFound > 0
ifTrue: [ self showPageCounts: each.].].
Dialog warn: ‘Done’. - 现在在底面板里单击<操作>菜单,选择 “Accept It” 。方法 getLogFilesForPageCounts 出现在方法面板里。你将会看到如下一个窗口:
图 10-3 系统浏览器中看到的新方法 getLogFilesForPageCounts - 在协议仍然选择着的情况下,如下更改方法面板中的代码:
startPageCountfilter := (Dialog request: ‘Please enter a filter ‘ initialAnswer: ‘ws00′).
(filter size) > 0
ifTrue: [self getLogFilesForPageCounts] - 现在在底面板里单击<操作>菜单,选择 “Accept It” 。方法 startPageCount 出现在方法面板里。你将会看到如下一个窗口:

图 10-4 系统浏览器中看到的新方法 startPageCount - 打开一个工作空间,输入如下内容:
WebLog new startPageCount高亮选择代码,然后选择 Do it 。
代码将会和前一课中一样运行,但现在它将统计那目录下的所有日志文件的页面计数统计,而不是针对一个文件。
- 打开文件浏览器,导航到日志文件所有的目录。如下图所示:

图 10-5 文件浏览器对话框里列出的我们的页面计数文件事实上软件并非一成不变的。人们需要在开发后或者在开发过程中对软件进行增强或扩充。这是无可厚非的。有人会发现在日志文件列表中列出来的除 ASP 文件以外,还有 HTM 文件。猜着了吧,我们的管理也需要计算这些。他们并不在乎只能有一次点击的很多的页面。事实上,不在乎那些不在访问量前十位中的那些页面。因此我们要做一下改变。 - 确认协议(protocol)面板里选择了实例(Instance)标签页。点击(选择) private 并点击(选择) showPageCounts: 方法。进行如下更改:
showPageCounts: aFile
| stream line bag xFound sort out outName |
bag := Bag new.
stream := (logDirectory, ‘\’, aFile) asFilename readStream.
[ stream atEnd ] whileFalse: [
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
line := line copyUpTo: $,.
xFound := (line findString: ‘.asp’ startingAt: 1) +
(line findString: ‘.htm’ startingAt: 1).
xFound > 0
ifTrue:[ bag add: line. ]. ].
stream close.
sort := SortedCollection sortBlock: [:a :b| a >= b].
bag valuesAndCountsDo: [ :each :count |
sort add: (Core.Association key: count value: each)].
outName := (logDirectory asFilename construct: aFile) asString.
out := (outName , ‘.stats’) asFilename writeStream.
1 to: 10 do: [ :each | out cr; nextPutAll: (sort at: each) printString.].
out close. - 现在在下面面板里单击<操作>菜单,并选择 “Accept” 项。这将会重新编译刚才输入的代码。排除任何排版差异,而且没有任何对话框出现,则 Smalltalk 就已经对代码做了相应更改并编译了。
- 打开一个工作空间,并输入如下内容:
WebLog new startPageCount高亮选择这些文本,然后选择 Do it.
注意:你也许会出现一个错误,出现一个如下图所示窗口:

图 10-6 著名的 Notifier 窗口
- 因为我们把统计文件写在与日志文件相同的目录里面,并且我们用日志文件的一部分作为统计文件名的一部分,我们的过滤器(查找 ws00 文件)就会包含进这些统计文件( .STATS )来。这会导致错误发生,我们并不想包含这些文件。我们将在下一课通过把统计文件命名为完全不同的名字来解决这个问题;但在现在,我们通过删除统计文件( .STATS )文件来解决。 即使调试器窗口已经关闭了,它还是会“锁住”它处理到的第一个 .STATS 文件。在 VisualWorks 完全退出之前这个文件是无法删除的。(有方法处理这种情况,但不在本课讨论范围之内)。因而,一定要严格按下面这个次序来进行处理。
- 点击 Terminate (终止)按钮
- 把更改导出到文件( File out )
- 退出 VisualWorks
- 删除 .log 目录中所有的 “.STATS” 文件
- 重新运行 VisualWorks
- 导入( File in )你的 WebLogStats.st 文件
- 打开一个工作空间,并输入如下内容:
WebLog new startPageCount高亮选择这些文本,并选择 Do it 项。
代码与前一课运行基本相同。不同之处,现在处理的页面计数统计是所在目录中所有的日志文件,并非一个文件。我们的 “统计” 文件现在包括了对 “HTM” 文件的计数,他们也应该出现在 “top ten” 列表之中。
- 打开文件列表( File List )对话框,导航到日志文件所在目录。如下图所示。
图 10-7 文件列表对话框中列出来的新的日志页面计数文件
改变的代码做了不少工作。让我们来解释以下,确保你要理解它们。
xFound := (line findString: ‘.asp’ startingAt: 1) +
(line findString: ‘.htm’ startingAt: 1).这个非常简单。 (line findString: ‘.asp’ startingAt: 1) 寻找一个 ASP 页, (line findString: ‘.htm’ startingAt: 1) 寻找一个 HTM 页。因为这些表达式返回一个数字( “ASP” 或者 “HTM” 在字符串中的开始位置),所以把两个值加起来,就完成了相同的事情(表示是否找到页面)。下一行测试是否是非零值。
1 to: 10 do: [ :each | out cr; nextPutAll: (sort at: each) printString.].这是一个固定次数循环的例子(1 to: 10 do:). 从 1 到 10 的数字将被传递 (每次进入循环体传递一个数字) 到临时变量 each 中,并在后续的代码片段中使用。因为我们有个容器,你可以认为容器中的每个元素有个数字或者叫索引。要引用容器中的每个元素,用 at: 方法。 (sort at: each) 语句就使用了这个技巧。
小结
学习如何把工作代码从单一工作空间( Workspace )移入类库里 (通过创建你自己的类和方法) 是一个跨跃。这将对你理解如何进行的能力提出挑战,尤其是如何把代码分割成几部分,并找到把几部分协调工作的方法。这同其他技能一样,通过更多的练习会变得容易起来。
往往当你移动代码时,会发现有些方法看上去很相似,所以就想通过重构努力把他们合并成为一个方法。下一课,你将看到这样一个例子,并实作合并方法,来使代码更加高效与易于重用。
你现在应该知道如何:
- 固定次数来遍历容器;
- 把代码从工作空间转到 VisualWorks 映像中;
- 用系统浏览器来更改现有方法。
第九课 最流行的竞争
我们已经计算了唯一点击计数。现在是检查我们网站哪些页面是最爱欢迎的时候了。为此,手头上的任务就是计算特定页面被访问的次数。计算应该相当简单;每次一个特定页面出现在日志文件里,就是一次点击。问题是日志文件同时也记录跟随网站页面一起出现的图像文件,诸如 JPG 和 GIF 文件等。这些我们不应该计算上。
仅仅有每个网页的点击数还不够。管理者想知道哪些文件是最受欢迎的,所谓“最受欢迎 TOP 10 ”。则下一个挑战即排列这些计数的顺序。
本课介绍了两个容器类: Bag 和 SortedCollection 。 并解释了为什么要用这两个类,他们帮助我们解决什么问题。
我们网站的所有网页都有 ASP 扩展名。 因此我们需要一行一行地读取日志文件并分析列出的文件是否 ASP 文件,然后进行计数。
Smalltalk 进行此种计数相当简单。 Smalltalk 一种解决方案是容器对象 Bag 。就像物理上的概念一样,这就是一个小包,你可以放入任何东西,并对放入的东西进行跟踪。并且如果你放入重复的东西,它会计数这重复东西的个数。
我们有了个数后,就需要进行排序的方法。 幸运的是, Smalltalk 还有另一种类型的容器类: SortedCollection 。因为我们用了两种类型的容器类, Smalltalk 很简单地把内容从一个容器转到另一个容器。因此要判断哪些网页是最受欢迎的,就很简单了。
因此,从文件的最上头开始(就像手工做一样),你的逻辑应该是这样:
- 取得日志文件的第一条项目,判断是否是个 ASP 文件。 如果是,放入小包里;
- 继续读文件,直到文件结尾。关闭文件;
- 把小包的计数放入到 SortedCollection 里(连同页面名);
- 显示 SortedCollection 的前10个。
在开始之前,你也许想看看关于 Bag 和 SortedCollection 的入门知识。
再看一下网站服务器日志文件。

图 9-1 VisualWorks 文件编辑器里的日志文件
注意,网页在每行的接近末尾的地方。每个网页名字前面有个正斜线(/) ,这就是我们标识文件名开始的方法。然而,前面的斜线 (/) 字符并不是唯一的 - 它仍然用于数据区域。总算我们可以查看着过去数据区域,下一个斜线 (/) 字符就代表了网页文件名的开始。这就是我们的策略。
- 第一步,打开一个工作空间。输入如下文本,然后高亮选择,点击<操作>菜单,并选择 “Do It” 。
|stream line |
stream := ‘ws000101.log’ asFilename readStream.
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
stream close.
line inspect.通过查看检视窗口,你将能够验证上面的代码确实从日志文件的第一行抽取了完整的网页文件名。

图 9-1 成功抽取一个网页文件名
许多新的方法进入了我们的例程。特别是奇怪的五行代码。让我们一行一行地来研究,确保你懂得每一行是如何工作的。|stream line |
stream := ‘ws000101.log’ asFilename readStream.
line := stream upTo: Character cr.这里没有新东西 - 前面已经看到这几行了。简言之,我们打开一个文件作为一个流( Stream ),读入第一行。 line 变量实际上存了一个 String 类的实例。
line := line copyFrom: 50 to: line size.要查看并过去第一个斜线 (/) 字符,我们让过去大约 50 个字符。这将使得我们恰好忽略掉在数据域里的第一个斜线 (/) 字符。方法 copyFrom:to: 让我们从整个字符串 (日志文件的整个一行) 劈去前50个字符,把从第51个字符开始到字符串结尾的字符串(行)留下给我们。
line := line copyFrom: (line indexOf: $/) to: line size.搭眼一看,这行代码显得很复杂。但实际上这与上行代码没什么区别。它同样是 copyFrom:to: 方法。但这里没用50作为 copyFrom: 的参数,而是用了在网页文件名前面出现的斜线 (/) 字符的位置作为参数。 indexOf: 方法,传给它一个字符参数 (在这里是前置的斜线 (/) 字符),返回这个字符出现在字符串中的位置。记住,我们要查找前置斜线 (/) 字符,我们要在它前面放一个美元符号 ($) 。这样,我们就把这一行在斜线 (/) 前面的东西统统劈去了。余下的东西则原封不动。
stream close.
line inspect.这里也没有任何新东西 - 在前面已经看到过了。简言之,我们关闭了文件(通过关闭流)并告诉 Smalltalk 在检视窗口里显示出 line 变量。
我们仍然有一些清洁工作要做(注意在检视窗口里有一些多余的逗号和短线)。我们要在循环处理文件和收集所有的 ASP 页面时清理掉它们。
- 如下相应的改变代码行,然后单击<操作>菜单,选择 “Do It” 。
|stream line bag xFound|
bag := Bag new.
stream := ‘ws000101.log’ asFilename readStream.
[ stream atEnd ] whileFalse: [
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
line := line copyUpTo: $,.
xFound := line findString: ‘.asp’ startingAt: 1.
xFound > 0
ifTrue:[ bag add: line. ]. ].
stream close.
bag inspect.通过查看检视窗口,你将会验证到上面的代码确实从日志文件(点击 self )里抽取了所有的 ASP 页面。 而且如果你点击了 content, 你将看到每页面的计数。

图 9-2 我们的 ASP 页面收集(小包)

图 9-3 在小包容器里面的每个 ASP 页面的计数我们现在需要排序。要达到这个目的,就要把小包里面的内容拷贝到 SortedCollection 里面。然而,小包( Bag )并非简单的数据结构。注意在图 9-3 中,当选择 contents 时,检视窗口告诉我们其内容实际上是个字典( Dictionary )。因此,一个小包( Bag ),不只是单个物品的集合( Set 之类 ),它实际上是物品的双重集合-第一部分是网页,第二部分是相应的计数。我们不能把 Bag 的内容简单地移到 Set 里面。
幸运的是, Smalltalk 的作者们已经意识到这个问题,并解决了我们的困境。他们创造了一个叫做 Association (联合)的容器类。这恰好是我们要的:一个数量“联合”一个网页。但我们反复说 Bag ,如何把一个数量和相联合的网页抽取出来?作者们仍然预先解决了,他们不是简单的用 do: 方法,而是写了一个更加适宜的方法 valuesAndCountsDo: ,它从 Bag 里面同时抽取两部分。
说的够多了,我们来写代码。
- 如下相应的改变代码行,单击<操作>菜单,选择 “Do It” 。
|stream line bag xFound sort|
bag := Bag new.
stream := ‘ws000101.log’ asFilename readStream.
[ stream atEnd ] whileFalse: [
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
line := line copyUpTo: $,.
xFound := line findString: ‘.asp’ startingAt: 1.
xFound > 0
ifTrue:[ bag add: line. ]. ].
stream close.
sort := SortedCollection sortBlock: [:a :b| a <= b].
bag valuesAndCountsDo: [ :each :count |
sort add: (Core.Association key: count value: each)].
sort do: [ :each | Transcript cr; show: each printString.].用副本窗口,验证一下代码确实对网页做了计数,并按顺序显示出来(从低到高)。

图 9-4 我们最受欢迎的网页最后4行代码是关键。让我们一行一行的来解释,以确保你能看懂每行代码是如何工作的。
sort := SortedCollection sortBlock: [:a :b | a <= b].因为我们想以逆序排列(从低到高),我们要用 SortedCollection 类的方法 sortBlock: 。 对于代码块 [:a :b| a <= b] 不要理解过多。这样思考就行: “对于 SortedCollection 中的任意两个元素(a 与 b), 使后面的一个元素大于或者等于前面的一个元素。”不像排序代码块,这只是 SortedCollection 类的一个普通初始化。
bag valuesAndCountsDo: [ :each :count |这基本上就是一个简单的 do: 循环块,只是传递给方法 valuesAndCountsDo: 两个参数,而不是一个。因此,本代码的开始部分声明了两个临时变量 (:each 和 :count)。参数 :each 代表网页的文件名,参数 :count 代表了相应的网页的计数。
sort add: (Core.Association key: count value: each)].这一行是例程的实际工作段,首先用 key:value: 方法创建了一个联合。这个方法需要两个参数。因为我们要排序页面计数,我们使第一个参数 key: 代表计数,第二个参数 value: 代表网页。一旦有了一个联合,我们就把它加入到 SortedCollection (sort) 中去。这行也是 valuesAndCountsDo: 循环块的一个终止点。
注意 Association 有一个前缀 Core 。语法 Core.Association 意思是 “用 Core 命名空间里的 Association 类。” 如果漏掉了 Core 命名空间, VisualWorks 会提醒你输入正确的命名空间;因为系统里有三个不同的 Association 类。
sort do: [ :each | Transcript cr; show: each printString.].最后,我们简单的在副本里显示 SortedCollection 的内容。一个简单的 do: 块足够了。
基本完工。我们仅用了13行代码来从日志文件中判断网页的计数,并按升序排列。如果你有认识的朋友或者家庭成员是程序员的话,让他们用他们喜欢的语言来写这个程序,看看他们要用多少行代码。
我们现在已经有了一个正常工作的程序内脏,让我们来稍加修饰。首先,我们要显示一个提示输入特定日志文件的对话框。这样,我们就能够对系统中任意的日志文件来计算最受欢迎的网页。第二,让我们不用副本,而用其他方法来显示计算结果。把结果写入一个文件如何?
- 如下相应的改变代码行,高亮选择,单击<操作>菜单,然后选择 “Do It” 。
|stream line bag xFound sort file|
bag := Bag new.
file := (Dialog request: ‘Enter file’ initialAnswer: ‘ws000101.log’) asFilename.
stream := file readStream.
[ stream atEnd ] whileFalse: [
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
line := line copyUpTo: $,.
xFound := line findString: ‘.asp’ startingAt: 1.
xFound > 0
ifTrue:[ bag add: line. ]. ].
stream close.
sort := SortedCollection sortBlock: [:a :b| a <= b].
bag valuesAndCountsDo: [ :each :count |
sort add: (Core.Association key: count value: each)].
sort do: [ :each | Transcript cr; show: each printString.].注意,我们现在提示输入日志文件名了。这完成了我们第一个修饰。现在我们试着把计算结果存到一个外部文件里。
- 如下相应的改变代码行,高亮选择,单击<操作>菜单,选择 “Do It” 。
|stream line bag xFound sort file out|
bag := Bag new.
file := (Dialog request: ‘Enter file’ initialAnswer: ‘ws000101.log’) asFilename.
stream := file readStream.
[ stream atEnd ] whileFalse: [
line := stream upTo: Character cr.
line := line copyFrom: 50 to: line size.
line := line copyFrom: (line indexOf: $/) to: line size.
line := line copyUpTo: $,.
xFound := line findString: ‘.asp’ startingAt: 1.
xFound > 0
ifTrue:[ bag add: line. ]. ].
stream close.
sort := SortedCollection sortBlock: [:a :b| a <= b].
bag valuesAndCountsDo: [ :each :count |
sort add: (Core.Association key: count value: each)].
out := ‘websitestats.txt’ asFilename writeStream.
sort do: [ :each | out cr; nextPutAll: each printString.].
out close.最后三行有点关键。让我们来研究一下,要确保弄懂。
out := ‘websitestats.txt’ asFilename writeStream.注意,打开/创建文件的语法和读取文件时打开文件的语法完全相同。一点区别就是用 writeStream 方法,而不是用 readStream 方法。如果文件 websitestats.txt 存在,它会复写了它。如果不存在,就创建它。
sort do: [ :each | out cr; nextPutAll: each printString.].这里我们用 do: 方法来遍历 sort 集合。临时变量 each 用于存放集合中每个元素的值。
我们首要做的是向输出文件写一个回车符号 (cr) 。注意分号。这表示我们的 out 对象也是接下来的表达式的接收者。 Stream 对象的 nextPutAll: 方法意味着接受一个传递来的参数 (each printString 里的 each 是 sort 集合里面给定的一个元素) 并把它放入到流中去。这个过程将重复直到到达集合的结尾为止。
out close.这简单地终止了流,因为这流是个外部文件,所以关闭了它。
- 为何不看一下输出文件?让我们用 VisualWorks 的文件浏览器来看看。(从 VisualWorks 的主启动窗口)选择菜单 File>>File Browser 或者点击工具条带眼镜的文件夹图标来打开文件浏览器。在 Show Files: 里输入 out* ,并按下回车。文件 websitestats.txt 将出现在上面的右面板里。点击来选择这个文件,你就可以看到它的内容。见图 9-5 。

图 9-5 我们输出的文件内容
小结
在本课中,你看到了用 Bag, Association, SortedCollection 来存储页面文件名和计数并排序的强大威力。下一课,我们将就在某一目录下的日志文件进行处理。我们将给出一个目录中一周、一月甚至一年的网页计数统计。
你现在应该知道如何:
- 识别 Bag ;
- 识别 SortedCollection ;
- 识别 Association ;
- 计数 Bag 中的元素个数;
- 从一个容器中把内容移动到另一个容器中;
- 创建一个外部文件。
第八课 保存你的工作
假定现在到了回家的时间了;亦或许外面雷阵雨太厉害。现在是时候保存你的工作了-我们不想丢失做过的工作。
本课讲解一个简单的方法来保存工作,并退出 VisualWorks 以后再进入恢复已经保存的工作。
- 如果系统浏览器打开了,选择它。如果还没有打开,从 VisualWorks 的主启动窗口的菜单里选择 System>>Browser ,或者单击第四个工具按钮,来打开系统浏览器。
- 在包面板(最左边的)里上下滚动,将会看到命名为 WebLogStats 的新包。
- 高亮选择 WebLogStats 包,单击<操作>菜单,选择 “File Out As…” 。
你将会看到如下一个窗口:

图 8-1 我们的包的<操作>菜单 - 一个本地的 “Save as…” 对话框出现(下面这个是 Windows XP 下的):

图 8-2 ( Windows XP 下)”File Out” 对话框 VisualWorks 将会用包的名字(这里是 WebLogStats )并加上扩展名 “.st” 来作为缺省的文件名。
- 单击保存文件的按钮(这里是 “Save” )。 VisualWorks 缺省用 VisualWorks “缺省目录” 来保存代码。后缀 “st” 代表 “Smalltalk” ,文件格式是 XML 格式。
- 关闭 VisualWorks 窗口,退出 VisualWorks 。从 VisualWorks 主启动窗口选择 File>>Exit VisualWorks… ,当询问你是否退出 VisualWorks 时,选择 Exit without Saving 。
- 重新运行 VisualWorks 。打开 File List 窗口(从主启动窗口选择菜单项 File>>File List ,或者按带眼镜的文件夹工具栏图标)。如下一个窗口将会出现:

图 8-3 文件浏览器对话框 - 在最上面的文本框里,输入星号( *.st )并按回车键。 VisualWorks 将刷新当前缺省目录的文件列表。你的文件列表可能会与下面的图片有所不同。你的对话框将会和下面的差不多:

图 8-4 用通配符和 st 来刷新后的文件列表对话框 - 在右边的上面板里,出现了 WebLogStats.st 文件。高亮选择这个文件。 VisualWorks 将在下面板里显示这个文件的内容。
图 8-5 在文件列表对话框里我们的 “st” 文件的内容 - 在 WebLogStats.st 文件仍然被高亮选择时,点击<操作>菜单,选择 “File In” 。

图 8-6 文件列表对话框里面的 “File In” 菜单项 VisualWorks 将装入 “st” 文件,并在系统副本里难是否成功取回。

图 8-7 “WebLogStats.st” 文件成功装入 - 启动系统浏览器(从 VisualWorks 主启动窗口,点击工具条第四个按钮,或者选择菜单 Browse>>System )。
- 向下滚动包列表,再向上找到 WebLogStats 包。你前面所有的代码都原封不动的回来了。这验证了 VisualWorks 成功地保存了工作,又成功地装入了工作。
小结
这个过程,非常明显的原因,被称为 “Filing Out/Filing In” 。这是保存工作和装入工作最简单的办法。它不仅保存了代码,并且保存了所有的类别、类、协议。
在下一课,你将添加到类中更多的功能。然后,如果你高兴,再保存它。
你现在应该知道如何:
- 用 File Out 过程来保存工作;
- 用 File In 过程来装入工作;
- 启动文件浏览器;
- 在文件浏览器里查看文件。
— 下一页 »